コード例 #1
0
ファイル: git.c プロジェクト: Ferryworld/git
static int run_builtin(struct cmd_struct *p, int argc, const char **argv)
{
	int status, help;
	struct stat st;
	const char *prefix;

	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);
		}

		if (use_pager == -1 && p->option & (RUN_SETUP | RUN_SETUP_GENTLY))
			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);
	}
	commit_pager_choice();

	if (!help && get_super_prefix()) {
		if (!(p->option & SUPPORT_SUPER_PREFIX))
			die("%s doesn't support --super-prefix", p->cmd);
		if (prefix)
			die("can't use --super-prefix from a subdirectory");
	}

	if (!help && p->option & NEED_WORK_TREE)
		setup_work_tree();

	trace_argv_printf(argv, "trace: built-in: git");

	status = p->fn(argc, argv, prefix);
	if (status)
		return status;

	/* Somebody closed stdout? */
	if (fstat(fileno(stdout), &st))
		return 0;
	/* Ignore write errors for pipes and sockets.. */
	if (S_ISFIFO(st.st_mode) || S_ISSOCK(st.st_mode))
		return 0;

	/* Check for ENOSPC and EIO errors.. */
	if (fflush(stdout))
		die_errno("write failure on standard output");
	if (ferror(stdout))
		die("unknown write failure on standard output");
	if (fclose(stdout))
		die_errno("close failed on standard output");
	return 0;
}
コード例 #2
0
ファイル: git.c プロジェクト: benpeart/git
static int run_builtin(struct cmd_struct *p, int argc, const char **argv)
{
	int status, help;
	struct stat st;
	const char *prefix;

	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);
		}

		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);
	}
	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();

	if (run_pre_command_hook(argv))
		die("pre-command hook aborted command");

	trace_argv_printf(argv, "trace: built-in: git");

	/*
	 * Validate the state of the cache entries in the index before and
	 * after running the command. Validation is only performed if the
	 * appropriate environment variable is set.
	 */
	validate_cache_entries(&the_index);
	exit_code = status = p->fn(argc, argv, prefix);
	validate_cache_entries(&the_index);
	if (status)
		return status;

	run_post_command_hook();

	/* Somebody closed stdout? */
	if (fstat(fileno(stdout), &st))
		return 0;
	/* Ignore write errors for pipes and sockets.. */
	if (S_ISFIFO(st.st_mode) || S_ISSOCK(st.st_mode))
		return 0;

	/* Check for ENOSPC and EIO errors.. */
	if (fflush(stdout))
		die_errno("write failure on standard output");
	if (ferror(stdout))
		die("unknown write failure on standard output");
	if (fclose(stdout))
		die_errno("close failed on standard output");
	return 0;
}
コード例 #3
0
ファイル: stash.c プロジェクト: PhilipOakley/git
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);
}
コード例 #4
0
ファイル: difftool.c プロジェクト: dscho/git
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);
}