git_config(git_alias_config);
if (alias_string) {
if (alias_string[0] == '!') {
+ if (*argcp > 1) {
+ int i, sz = PATH_MAX;
+ char *s = xmalloc(sz), *new_alias = s;
+
+ add_to_string(&s, &sz, alias_string, 0);
+ free(alias_string);
+ alias_string = new_alias;
+ for (i = 1; i < *argcp &&
+ !add_to_string(&s, &sz, " ", 0) &&
+ !add_to_string(&s, &sz, (*argv)[i], 1)
+ ; i++)
+ ; /* do nothing */
+ if (!sz)
+ die("Too many or long arguments");
+ }
trace_printf("trace: alias to shell cmd: %s => %s\n",
alias_command, alias_string + 1);
ret = system(alias_string + 1);
prefix = setup_git_directory();
if (p->option & USE_PAGER)
setup_pager();
- if ((p->option & NEED_WORK_TREE) &&
- (!is_inside_work_tree() || is_inside_git_dir()))
- die("%s must be run in a work tree", p->cmd);
+ if (p->option & NEED_WORK_TREE) {
+ const char *work_tree = get_git_work_tree();
+ const char *git_dir = get_git_dir();
+ if (!is_absolute_path(git_dir))
+ set_git_dir(make_absolute_path(git_dir));
+ if (!work_tree || chdir(work_tree))
+ die("%s must be run in a work tree", p->cmd);
+ }
trace_argv_printf(argv, argc, "trace: built-in: git");
status = p->fn(argc, argv, prefix);
const char *cmd = argv[0];
static struct cmd_struct commands[] = {
{ "add", cmd_add, RUN_SETUP | NEED_WORK_TREE },
- { "annotate", cmd_annotate, RUN_SETUP | USE_PAGER },
+ { "annotate", cmd_annotate, RUN_SETUP },
{ "apply", cmd_apply },
{ "archive", cmd_archive },
{ "blame", cmd_blame, RUN_SETUP },
{ "mv", cmd_mv, RUN_SETUP | NEED_WORK_TREE },
{ "name-rev", cmd_name_rev, RUN_SETUP },
{ "pack-objects", cmd_pack_objects, RUN_SETUP },
- { "pickaxe", cmd_blame, RUN_SETUP | USE_PAGER },
+ { "pickaxe", cmd_blame, RUN_SETUP },
{ "prune", cmd_prune, RUN_SETUP },
{ "prune-packed", cmd_prune_packed, RUN_SETUP },
{ "push", cmd_push, RUN_SETUP },
cmd = argv[0];
/*
- * We search for git commands in the following order:
- * - git_exec_path()
- * - the path of the "git" command if we could find it
- * in $0
- * - the regular PATH.
+ * We execute external git command via execv_git_cmd(),
+ * which looks at "--exec-path" option, GIT_EXEC_PATH
+ * environment, and $(gitexecdir) in Makefile while built,
+ * in this order. For scripted commands, we prepend
+ * the value of the exec_path variable to the PATH.
*/
if (exec_path)
prepend_to_path(exec_path, strlen(exec_path));