aboutsummaryrefslogtreecommitdiffstats
path: root/git.c
diff options
context:
space:
mode:
Diffstat (limited to 'git.c')
-rw-r--r--git.c183
1 files changed, 97 insertions, 86 deletions
diff --git a/git.c b/git.c
index 18bed9a996..654d615a18 100644
--- a/git.c
+++ b/git.c
@@ -1,10 +1,20 @@
#include "builtin.h"
#include "config.h"
+#include "environment.h"
#include "exec-cmd.h"
+#include "gettext.h"
#include "help.h"
+#include "object-file.h"
+#include "pager.h"
+#include "read-cache-ll.h"
#include "run-command.h"
#include "alias.h"
+#include "replace-object.h"
+#include "setup.h"
+#include "attr.h"
#include "shallow.h"
+#include "trace.h"
+#include "trace2.h"
#define RUN_SETUP (1<<0)
#define RUN_SETUP_GENTLY (1<<1)
@@ -14,9 +24,8 @@
* RUN_SETUP for reading from the configuration file.
*/
#define NEED_WORK_TREE (1<<3)
-#define SUPPORT_SUPER_PREFIX (1<<4)
-#define DELAY_PAGER_CONFIG (1<<5)
-#define NO_PARSEOPT (1<<6) /* parse-options is not used */
+#define DELAY_PAGER_CONFIG (1<<4)
+#define NO_PARSEOPT (1<<5) /* parse-options is not used */
struct cmd_struct {
const char *cmd;
@@ -25,12 +34,11 @@ struct cmd_struct {
};
const char git_usage_string[] =
- N_("git [--version] [--help] [-C <path>] [-c <name>=<value>]\n"
+ N_("git [-v | --version] [-h | --help] [-C <path>] [-c <name>=<value>]\n"
" [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]\n"
" [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--bare]\n"
" [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]\n"
- " [--super-prefix=<path>] [--config-env=<name>=<envvar>]\n"
- " <command> [<args>]");
+ " [--config-env=<name>=<envvar>] <command> [<args>]");
const char git_more_info_string[] =
N_("'git help -a' and 'git help -g' list available subcommands and some\n"
@@ -146,7 +154,8 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)
* commands can be written with "--" prepended
* to make them look like flags.
*/
- if (!strcmp(cmd, "--help") || !strcmp(cmd, "--version"))
+ if (!strcmp(cmd, "--help") || !strcmp(cmd, "-h") ||
+ !strcmp(cmd, "--version") || !strcmp(cmd, "-v"))
break;
/*
@@ -178,14 +187,19 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)
use_pager = 0;
if (envchanged)
*envchanged = 1;
+ } else if (!strcmp(cmd, "--no-lazy-fetch")) {
+ fetch_if_missing = 0;
+ setenv(NO_LAZY_FETCH_ENVIRONMENT, "1", 1);
+ if (envchanged)
+ *envchanged = 1;
} else if (!strcmp(cmd, "--no-replace-objects")) {
- read_replace_refs = 0;
+ disable_replace_refs();
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" ));
+ fprintf(stderr, _("no directory given for '%s' option\n" ), "--git-dir");
usage(git_usage_string);
}
setenv(GIT_DIR_ENVIRONMENT, (*argv)[1], 1);
@@ -213,7 +227,7 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)
*envchanged = 1;
} else if (!strcmp(cmd, "--work-tree")) {
if (*argc < 2) {
- fprintf(stderr, _("no directory given for --work-tree\n" ));
+ fprintf(stderr, _("no directory given for '%s' option\n" ), "--work-tree");
usage(git_usage_string);
}
setenv(GIT_WORK_TREE_ENVIRONMENT, (*argv)[1], 1);
@@ -225,20 +239,6 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)
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;
@@ -297,7 +297,7 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)
*envchanged = 1;
} else if (!strcmp(cmd, "-C")) {
if (*argc < 2) {
- fprintf(stderr, _("no directory given for -C\n" ));
+ fprintf(stderr, _("no directory given for '%s' option\n" ), "-C");
usage(git_usage_string);
}
if ((*argv)[1][0]) {
@@ -322,6 +322,21 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)
} else {
exit(list_cmds(cmd));
}
+ } else if (!strcmp(cmd, "--attr-source")) {
+ if (*argc < 2) {
+ fprintf(stderr, _("no attribute source given for --attr-source\n" ));
+ usage(git_usage_string);
+ }
+ setenv(GIT_ATTR_SOURCE_ENVIRONMENT, (*argv)[1], 1);
+ if (envchanged)
+ *envchanged = 1;
+ (*argv)++;
+ (*argc)--;
+ } else if (skip_prefix(cmd, "--attr-source=", &cmd)) {
+ set_git_attr_source(cmd);
+ setenv(GIT_ATTR_SOURCE_ENVIRONMENT, cmd, 1);
+ if (envchanged)
+ *envchanged = 1;
} else {
fprintf(stderr, _("unknown option: %s\n"), cmd);
usage(git_usage_string);
@@ -364,8 +379,6 @@ static int handle_alias(int *argcp, const char ***argv)
strvec_pushv(&child.args, (*argv) + 1);
trace2_cmd_alias(alias_command, child.args.v);
- trace2_cmd_list_config();
- trace2_cmd_list_env_vars();
trace2_cmd_name("_run_shell_alias_");
ret = run_command(&child);
@@ -402,8 +415,6 @@ static int handle_alias(int *argcp, const char ***argv)
COPY_ARRAY(new_argv + count, *argv + 1, *argcp);
trace2_cmd_alias(alias_command, new_argv);
- trace2_cmd_list_config();
- trace2_cmd_list_env_vars();
*argv = new_argv;
*argcp += count - 1;
@@ -421,41 +432,38 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv)
int status, help;
struct stat st;
const char *prefix;
+ int run_setup = (p->option & (RUN_SETUP | RUN_SETUP_GENTLY));
- prefix = NULL;
help = argc == 2 && !strcmp(argv[1], "-h");
- if (!help) {
- if (p->option & RUN_SETUP)
- prefix = setup_git_directory();
- else if (p->option & RUN_SETUP_GENTLY) {
- int nongit_ok;
- prefix = setup_git_directory_gently(&nongit_ok);
- }
- precompose_argv_prefix(argc, argv, NULL);
- if (use_pager == -1 && p->option & (RUN_SETUP | RUN_SETUP_GENTLY) &&
- !(p->option & DELAY_PAGER_CONFIG))
- use_pager = check_pager_config(p->cmd);
- if (use_pager == -1 && p->option & USE_PAGER)
- use_pager = 1;
-
- if ((p->option & (RUN_SETUP | RUN_SETUP_GENTLY)) &&
- startup_info->have_repository) /* get_git_dir() may set up repo, avoid that */
- trace_repo_setup(prefix);
+ if (help && (run_setup & RUN_SETUP))
+ /* demote to GENTLY to allow 'git cmd -h' outside repo */
+ run_setup = RUN_SETUP_GENTLY;
+
+ if (run_setup & RUN_SETUP) {
+ prefix = setup_git_directory();
+ } else if (run_setup & RUN_SETUP_GENTLY) {
+ int nongit_ok;
+ prefix = setup_git_directory_gently(&nongit_ok);
+ } else {
+ prefix = NULL;
}
+ assert(!prefix || *prefix);
+ precompose_argv_prefix(argc, argv, NULL);
+ if (use_pager == -1 && run_setup &&
+ !(p->option & DELAY_PAGER_CONFIG))
+ use_pager = check_pager_config(p->cmd);
+ if (use_pager == -1 && p->option & USE_PAGER)
+ use_pager = 1;
+ if (run_setup && startup_info->have_repository)
+ /* get_git_dir() may set up repo, avoid that */
+ trace_repo_setup();
commit_pager_choice();
- if (!help && get_super_prefix()) {
- if (!(p->option & SUPPORT_SUPER_PREFIX))
- die(_("%s doesn't support --super-prefix"), p->cmd);
- }
-
if (!help && p->option & NEED_WORK_TREE)
setup_work_tree();
trace_argv_printf(argv, "trace: built-in: git");
trace2_cmd_name(p->cmd);
- trace2_cmd_list_config();
- trace2_cmd_list_env_vars();
validate_cache_entries(the_repository->index);
status = p->fn(argc, argv, prefix);
@@ -484,14 +492,14 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv)
static struct cmd_struct commands[] = {
{ "add", cmd_add, RUN_SETUP | NEED_WORK_TREE },
{ "am", cmd_am, RUN_SETUP | NEED_WORK_TREE },
- { "annotate", cmd_annotate, RUN_SETUP | NO_PARSEOPT },
+ { "annotate", cmd_annotate, RUN_SETUP },
{ "apply", cmd_apply, RUN_SETUP_GENTLY },
{ "archive", cmd_archive, RUN_SETUP_GENTLY },
- { "bisect--helper", cmd_bisect__helper, RUN_SETUP },
+ { "bisect", cmd_bisect, RUN_SETUP },
{ "blame", cmd_blame, RUN_SETUP },
{ "branch", cmd_branch, RUN_SETUP | DELAY_PAGER_CONFIG },
{ "bugreport", cmd_bugreport, RUN_SETUP_GENTLY },
- { "bundle", cmd_bundle, RUN_SETUP_GENTLY | NO_PARSEOPT },
+ { "bundle", cmd_bundle, RUN_SETUP_GENTLY },
{ "cat-file", cmd_cat_file, RUN_SETUP },
{ "check-attr", cmd_check_attr, RUN_SETUP },
{ "check-ignore", cmd_check_ignore, RUN_SETUP | NEED_WORK_TREE },
@@ -499,7 +507,7 @@ static struct cmd_struct commands[] = {
{ "check-ref-format", cmd_check_ref_format, NO_PARSEOPT },
{ "checkout", cmd_checkout, RUN_SETUP | NEED_WORK_TREE },
{ "checkout--worker", cmd_checkout__worker,
- RUN_SETUP | NEED_WORK_TREE | SUPPORT_SUPER_PREFIX },
+ RUN_SETUP | NEED_WORK_TREE },
{ "checkout-index", cmd_checkout_index,
RUN_SETUP | NEED_WORK_TREE},
{ "cherry", cmd_cherry, RUN_SETUP },
@@ -509,7 +517,7 @@ static struct cmd_struct commands[] = {
{ "column", cmd_column, RUN_SETUP_GENTLY },
{ "commit", cmd_commit, RUN_SETUP | NEED_WORK_TREE },
{ "commit-graph", cmd_commit_graph, RUN_SETUP },
- { "commit-tree", cmd_commit_tree, RUN_SETUP | NO_PARSEOPT },
+ { "commit-tree", cmd_commit_tree, RUN_SETUP },
{ "config", cmd_config, RUN_SETUP_GENTLY | DELAY_PAGER_CONFIG },
{ "count-objects", cmd_count_objects, RUN_SETUP },
{ "credential", cmd_credential, RUN_SETUP_GENTLY | NO_PARSEOPT },
@@ -517,12 +525,12 @@ static struct cmd_struct commands[] = {
{ "credential-cache--daemon", cmd_credential_cache_daemon },
{ "credential-store", cmd_credential_store },
{ "describe", cmd_describe, RUN_SETUP },
+ { "diagnose", cmd_diagnose, RUN_SETUP_GENTLY },
{ "diff", cmd_diff, NO_PARSEOPT },
{ "diff-files", cmd_diff_files, RUN_SETUP | NEED_WORK_TREE | NO_PARSEOPT },
{ "diff-index", cmd_diff_index, RUN_SETUP | NO_PARSEOPT },
{ "diff-tree", cmd_diff_tree, RUN_SETUP | NO_PARSEOPT },
{ "difftool", cmd_difftool, RUN_SETUP_GENTLY },
- { "env--helper", cmd_env__helper },
{ "fast-export", cmd_fast_export, RUN_SETUP },
{ "fast-import", cmd_fast_import, RUN_SETUP | NO_PARSEOPT },
{ "fetch", cmd_fetch, RUN_SETUP },
@@ -533,11 +541,13 @@ static struct cmd_struct commands[] = {
{ "format-patch", cmd_format_patch, RUN_SETUP },
{ "fsck", cmd_fsck, RUN_SETUP },
{ "fsck-objects", cmd_fsck, RUN_SETUP },
+ { "fsmonitor--daemon", cmd_fsmonitor__daemon, RUN_SETUP },
{ "gc", cmd_gc, RUN_SETUP },
{ "get-tar-commit-id", cmd_get_tar_commit_id, NO_PARSEOPT },
{ "grep", cmd_grep, RUN_SETUP_GENTLY },
{ "hash-object", cmd_hash_object },
{ "help", cmd_help },
+ { "hook", cmd_hook, RUN_SETUP },
{ "index-pack", cmd_index_pack, RUN_SETUP_GENTLY | NO_PARSEOPT },
{ "init", cmd_init_db },
{ "init-db", cmd_init_db },
@@ -546,9 +556,9 @@ static struct cmd_struct commands[] = {
{ "ls-files", cmd_ls_files, RUN_SETUP },
{ "ls-remote", cmd_ls_remote, RUN_SETUP_GENTLY },
{ "ls-tree", cmd_ls_tree, RUN_SETUP },
- { "mailinfo", cmd_mailinfo, RUN_SETUP_GENTLY | NO_PARSEOPT },
+ { "mailinfo", cmd_mailinfo, RUN_SETUP_GENTLY },
{ "mailsplit", cmd_mailsplit, NO_PARSEOPT },
- { "maintenance", cmd_maintenance, RUN_SETUP | NO_PARSEOPT },
+ { "maintenance", cmd_maintenance, RUN_SETUP },
{ "merge", cmd_merge, RUN_SETUP | NEED_WORK_TREE },
{ "merge-base", cmd_merge_base, RUN_SETUP },
{ "merge-file", cmd_merge_file, RUN_SETUP_GENTLY },
@@ -558,10 +568,10 @@ static struct cmd_struct commands[] = {
{ "merge-recursive-ours", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE | NO_PARSEOPT },
{ "merge-recursive-theirs", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE | NO_PARSEOPT },
{ "merge-subtree", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE | NO_PARSEOPT },
- { "merge-tree", cmd_merge_tree, RUN_SETUP | NO_PARSEOPT },
- { "mktag", cmd_mktag, RUN_SETUP | NO_PARSEOPT },
+ { "merge-tree", cmd_merge_tree, RUN_SETUP },
+ { "mktag", cmd_mktag, RUN_SETUP },
{ "mktree", cmd_mktree, RUN_SETUP },
- { "multi-pack-index", cmd_multi_pack_index, RUN_SETUP_GENTLY },
+ { "multi-pack-index", cmd_multi_pack_index, RUN_SETUP },
{ "mv", cmd_mv, RUN_SETUP | NEED_WORK_TREE },
{ "name-rev", cmd_name_rev, RUN_SETUP },
{ "notes", cmd_notes, RUN_SETUP },
@@ -575,9 +585,8 @@ static struct cmd_struct commands[] = {
{ "pull", cmd_pull, RUN_SETUP | NEED_WORK_TREE },
{ "push", cmd_push, RUN_SETUP },
{ "range-diff", cmd_range_diff, RUN_SETUP | USE_PAGER },
- { "read-tree", cmd_read_tree, RUN_SETUP | SUPPORT_SUPER_PREFIX},
+ { "read-tree", cmd_read_tree, RUN_SETUP },
{ "rebase", cmd_rebase, RUN_SETUP | NEED_WORK_TREE },
- { "rebase--interactive", cmd_rebase__interactive, RUN_SETUP | NEED_WORK_TREE },
{ "receive-pack", cmd_receive_pack },
{ "reflog", cmd_reflog, RUN_SETUP },
{ "remote", cmd_remote, RUN_SETUP },
@@ -585,6 +594,7 @@ static struct cmd_struct commands[] = {
{ "remote-fd", cmd_remote_fd, NO_PARSEOPT },
{ "repack", cmd_repack, RUN_SETUP },
{ "replace", cmd_replace, RUN_SETUP },
+ { "replay", cmd_replay, RUN_SETUP },
{ "rerere", cmd_rerere, RUN_SETUP },
{ "reset", cmd_reset, RUN_SETUP },
{ "restore", cmd_restore, RUN_SETUP | NEED_WORK_TREE },
@@ -598,12 +608,12 @@ static struct cmd_struct commands[] = {
{ "show-branch", cmd_show_branch, RUN_SETUP },
{ "show-index", cmd_show_index, RUN_SETUP_GENTLY },
{ "show-ref", cmd_show_ref, RUN_SETUP },
- { "sparse-checkout", cmd_sparse_checkout, RUN_SETUP | NEED_WORK_TREE },
+ { "sparse-checkout", cmd_sparse_checkout, RUN_SETUP },
{ "stage", cmd_add, RUN_SETUP | NEED_WORK_TREE },
{ "stash", cmd_stash, RUN_SETUP | NEED_WORK_TREE },
{ "status", cmd_status, RUN_SETUP | NEED_WORK_TREE },
{ "stripspace", cmd_stripspace },
- { "submodule--helper", cmd_submodule__helper, RUN_SETUP | SUPPORT_SUPER_PREFIX | NO_PARSEOPT },
+ { "submodule--helper", cmd_submodule__helper, RUN_SETUP },
{ "switch", cmd_switch, RUN_SETUP | NEED_WORK_TREE },
{ "symbolic-ref", cmd_symbolic_ref, RUN_SETUP },
{ "tag", cmd_tag, RUN_SETUP | DELAY_PAGER_CONFIG },
@@ -621,7 +631,7 @@ static struct cmd_struct commands[] = {
{ "verify-tag", cmd_verify_tag, RUN_SETUP },
{ "version", cmd_version },
{ "whatchanged", cmd_whatchanged, RUN_SETUP },
- { "worktree", cmd_worktree, RUN_SETUP | NO_PARSEOPT },
+ { "worktree", cmd_worktree, RUN_SETUP },
{ "write-tree", cmd_write_tree, RUN_SETUP },
};
@@ -720,9 +730,6 @@ static void execv_dashed_external(const char **argv)
struct child_process cmd = CHILD_PROCESS_INIT;
int status;
- if (get_super_prefix())
- die(_("%s doesn't support --super-prefix"), argv[0]);
-
if (use_pager == -1 && !is_builtin(argv[0]))
use_pager = check_pager_config(argv[0]);
commit_pager_choice();
@@ -780,7 +787,7 @@ static int run_argv(int *argcp, const char ***argv)
if (!done_alias)
handle_builtin(*argcp, *argv);
else if (get_builtin(**argv)) {
- struct strvec args = STRVEC_INIT;
+ struct child_process cmd = CHILD_PROCESS_INIT;
int i;
/*
@@ -792,23 +799,23 @@ static int run_argv(int *argcp, const char ***argv)
*/
trace2_cmd_name("_run_git_alias_");
- if (get_super_prefix())
- die("%s doesn't support --super-prefix", **argv);
-
commit_pager_choice();
- strvec_push(&args, "git");
+ strvec_push(&cmd.args, "git");
for (i = 0; i < *argcp; i++)
- strvec_push(&args, (*argv)[i]);
+ strvec_push(&cmd.args, (*argv)[i]);
- trace_argv_printf(args.v, "trace: exec:");
+ trace_argv_printf(cmd.args.v, "trace: exec:");
/*
* if we fail because the command is not found, it is
* OK to return. Otherwise, we just pass along the status code.
*/
- i = run_command_v_opt_tr2(args.v, RUN_SILENT_EXEC_FAILURE |
- RUN_CLEAN_ON_EXIT | RUN_WAIT_AFTER_CLEAN, "git_alias");
+ cmd.silent_exec_failure = 1;
+ cmd.clean_on_exit = 1;
+ cmd.wait_after_clean = 1;
+ cmd.trace2_child_class = "git_alias";
+ i = run_command(&cmd);
if (i >= 0 || errno != ENOENT)
exit(i);
die("could not execute builtin %s", **argv);
@@ -887,10 +894,8 @@ int cmd_main(int argc, const char **argv)
argv++;
argc--;
handle_options(&argv, &argc, NULL);
- if (argc > 0) {
- /* translate --help and --version into commands */
- skip_prefix(argv[0], "--", &argv[0]);
- } else {
+
+ if (!argc) {
/* The user didn't specify a command; give them help */
commit_pager_choice();
printf(_("usage: %s\n\n"), git_usage_string);
@@ -898,6 +903,12 @@ int cmd_main(int argc, const char **argv)
printf("\n%s\n", _(git_more_info_string));
exit(1);
}
+
+ if (!strcmp("--version", argv[0]) || !strcmp("-v", argv[0]))
+ argv[0] = "version";
+ else if (!strcmp("--help", argv[0]) || !strcmp("-h", argv[0]))
+ argv[0] = "help";
+
cmd = argv[0];
/*