Ejemplo n.º 1
0
static void save_opts(struct replay_opts *opts)
{
	const char *opts_file = git_path_opts_file();

	if (opts->no_commit)
		git_config_set_in_file(opts_file, "options.no-commit", "true");
	if (opts->edit)
		git_config_set_in_file(opts_file, "options.edit", "true");
	if (opts->signoff)
		git_config_set_in_file(opts_file, "options.signoff", "true");
	if (opts->record_origin)
		git_config_set_in_file(opts_file, "options.record-origin", "true");
	if (opts->allow_ff)
		git_config_set_in_file(opts_file, "options.allow-ff", "true");
	if (opts->mainline) {
		struct strbuf buf = STRBUF_INIT;
		strbuf_addf(&buf, "%d", opts->mainline);
		git_config_set_in_file(opts_file, "options.mainline", buf.buf);
		strbuf_release(&buf);
	}
	if (opts->strategy)
		git_config_set_in_file(opts_file, "options.strategy", opts->strategy);
	if (opts->gpg_sign)
		git_config_set_in_file(opts_file, "options.gpg-sign", opts->gpg_sign);
	if (opts->xopts) {
		int i;
		for (i = 0; i < opts->xopts_nr; i++)
			git_config_set_multivar_in_file(opts_file,
							"options.strategy-option",
							opts->xopts[i], "^$", 0);
	}
}
Ejemplo n.º 2
0
/*
 * Try to update the "path" entry in the "submodule.<name>" section of the
 * .gitmodules file. Return 0 only if a .gitmodules file was found, a section
 * with the correct path=<oldpath> setting was found and we could update it.
 */
int update_path_in_gitmodules(const char *oldpath, const char *newpath)
{
	struct strbuf entry = STRBUF_INIT;
	struct string_list_item *path_option;

	if (!file_exists(".gitmodules")) /* Do nothing without .gitmodules */
		return -1;

	if (gitmodules_is_unmerged)
		die(_("Cannot change unmerged .gitmodules, resolve merge conflicts first"));

	path_option = unsorted_string_list_lookup(&config_name_for_path, oldpath);
	if (!path_option) {
		warning(_("Could not find section in .gitmodules where path=%s"), oldpath);
		return -1;
	}
	strbuf_addstr(&entry, "submodule.");
	strbuf_addstr(&entry, path_option->util);
	strbuf_addstr(&entry, ".path");
	if (git_config_set_in_file(".gitmodules", entry.buf, newpath) < 0) {
		/* Maybe the user already did that, don't error out here */
		warning(_("Could not update .gitmodules entry %s"), entry.buf);
		strbuf_release(&entry);
		return -1;
	}
	strbuf_release(&entry);
	return 0;
}
Ejemplo n.º 3
0
/* Update gitfile and core.worktree setting to connect work tree and git dir */
void connect_work_tree_and_git_dir(const char *work_tree, const char *git_dir)
{
	struct strbuf file_name = STRBUF_INIT;
	struct strbuf rel_path = STRBUF_INIT;
	const char *real_work_tree = xstrdup(real_path(work_tree));
	FILE *fp;

	/* Update gitfile */
	strbuf_addf(&file_name, "%s/.git", work_tree);
	fp = fopen(file_name.buf, "w");
	if (!fp)
		die(_("Could not create git link %s"), file_name.buf);
	fprintf(fp, "gitdir: %s\n", relative_path(git_dir, real_work_tree,
						  &rel_path));
	fclose(fp);

	/* Update core.worktree setting */
	strbuf_reset(&file_name);
	strbuf_addf(&file_name, "%s/config", git_dir);
	if (git_config_set_in_file(file_name.buf, "core.worktree",
				   relative_path(real_work_tree, git_dir,
						 &rel_path)))
		die(_("Could not set core.worktree in %s"),
		    file_name.buf);

	strbuf_release(&file_name);
	strbuf_release(&rel_path);
	free((void *)real_work_tree);
}
Ejemplo n.º 4
0
/*
 * Try to update the "path" entry in the "submodule.<name>" section of the
 * .gitmodules file. Return 0 only if a .gitmodules file was found, a section
 * with the correct path=<oldpath> setting was found and we could update it.
 */
int update_path_in_gitmodules(const char *oldpath, const char *newpath)
{
	struct strbuf entry = STRBUF_INIT;
	const struct submodule *submodule;

	if (!file_exists(".gitmodules")) /* Do nothing without .gitmodules */
		return -1;

	if (gitmodules_is_unmerged)
		die(_("Cannot change unmerged .gitmodules, resolve merge conflicts first"));

	submodule = submodule_from_path(null_sha1, oldpath);
	if (!submodule || !submodule->name) {
		warning(_("Could not find section in .gitmodules where path=%s"), oldpath);
		return -1;
	}
	strbuf_addstr(&entry, "submodule.");
	strbuf_addstr(&entry, submodule->name);
	strbuf_addstr(&entry, ".path");
	if (git_config_set_in_file(".gitmodules", entry.buf, newpath) < 0) {
		/* Maybe the user already did that, don't error out here */
		warning(_("Could not update .gitmodules entry %s"), entry.buf);
		strbuf_release(&entry);
		return -1;
	}
	strbuf_release(&entry);
	return 0;
}
Ejemplo n.º 5
0
/* Update gitfile and core.worktree setting to connect work tree and git dir */
void connect_work_tree_and_git_dir(const char *work_tree, const char *git_dir)
{
	struct strbuf file_name = STRBUF_INIT;
	struct strbuf rel_path = STRBUF_INIT;
	const char *real_work_tree = xstrdup(real_path(work_tree));

	/* Update gitfile */
	strbuf_addf(&file_name, "%s/.git", work_tree);
	write_file(file_name.buf, "gitdir: %s",
		   relative_path(git_dir, real_work_tree, &rel_path));

	/* Update core.worktree setting */
	strbuf_reset(&file_name);
	strbuf_addf(&file_name, "%s/config", git_dir);
	git_config_set_in_file(file_name.buf, "core.worktree",
			       relative_path(real_work_tree, git_dir,
					     &rel_path));

	strbuf_release(&file_name);
	strbuf_release(&rel_path);
	free((void *)real_work_tree);
}
Ejemplo n.º 6
0
int cmd_config(int argc, const char **argv, const char *prefix)
{
    int nongit = !startup_info->have_repository;
    char *value;

    given_config_file = getenv(CONFIG_ENVIRONMENT);

    argc = parse_options(argc, argv, prefix, builtin_config_options,
                         builtin_config_usage,
                         PARSE_OPT_STOP_AT_NON_OPTION);

    if (use_global_config + use_system_config + use_local_config + !!given_config_file > 1) {
        error("only one config file at a time.");
        usage_with_options(builtin_config_usage, builtin_config_options);
    }

    if (use_global_config) {
        char *user_config = NULL;
        char *xdg_config = NULL;

        home_config_paths(&user_config, &xdg_config, "config");

        if (access(user_config, R_OK) && !access(xdg_config, R_OK))
            given_config_file = xdg_config;
        else if (user_config)
            given_config_file = user_config;
        else
            die("$HOME not set");
    }
    else if (use_system_config)
        given_config_file = git_etc_gitconfig();
    else if (use_local_config)
        given_config_file = git_pathdup("config");
    else if (given_config_file) {
        if (!is_absolute_path(given_config_file) && prefix)
            given_config_file =
                xstrdup(prefix_filename(prefix,
                                        strlen(prefix),
                                        given_config_file));
    }

    if (respect_includes == -1)
        respect_includes = !given_config_file;

    if (end_null) {
        term = '\0';
        delim = '\n';
        key_delim = '\n';
    }

    if (HAS_MULTI_BITS(types)) {
        error("only one type at a time.");
        usage_with_options(builtin_config_usage, builtin_config_options);
    }

    if (get_color_slot)
        actions |= ACTION_GET_COLOR;
    if (get_colorbool_slot)
        actions |= ACTION_GET_COLORBOOL;

    if ((get_color_slot || get_colorbool_slot) && types) {
        error("--get-color and variable type are incoherent");
        usage_with_options(builtin_config_usage, builtin_config_options);
    }

    if (HAS_MULTI_BITS(actions)) {
        error("only one action at a time.");
        usage_with_options(builtin_config_usage, builtin_config_options);
    }
    if (actions == 0)
        switch (argc) {
        case 1:
            actions = ACTION_GET;
            break;
        case 2:
            actions = ACTION_SET;
            break;
        case 3:
            actions = ACTION_SET_ALL;
            break;
        default:
            usage_with_options(builtin_config_usage, builtin_config_options);
        }

    if (actions == ACTION_LIST) {
        check_argc(argc, 0, 0);
        if (git_config_with_options(show_all_config, NULL,
                                    given_config_file,
                                    respect_includes) < 0) {
            if (given_config_file)
                die_errno("unable to read config file '%s'",
                          given_config_file);
            else
                die("error processing config file(s)");
        }
    }
    else if (actions == ACTION_EDIT) {
        check_argc(argc, 0, 0);
        if (!given_config_file && nongit)
            die("not in a git directory");
        git_config(git_default_config, NULL);
        launch_editor(given_config_file ?
                      given_config_file : git_path("config"),
                      NULL, NULL);
    }
    else if (actions == ACTION_SET) {
        int ret;
        check_argc(argc, 2, 2);
        value = normalize_value(argv[0], argv[1]);
        ret = git_config_set_in_file(given_config_file, argv[0], value);
        if (ret == CONFIG_NOTHING_SET)
            error("cannot overwrite multiple values with a single value\n"
                  "       Use a regexp, --add or --replace-all to change %s.", argv[0]);
        return ret;
    }
    else if (actions == ACTION_SET_ALL) {
        check_argc(argc, 2, 3);
        value = normalize_value(argv[0], argv[1]);
        return git_config_set_multivar_in_file(given_config_file,
                                               argv[0], value, argv[2], 0);
    }
    else if (actions == ACTION_ADD) {
        check_argc(argc, 2, 2);
        value = normalize_value(argv[0], argv[1]);
        return git_config_set_multivar_in_file(given_config_file,
                                               argv[0], value, "^$", 0);
    }
    else if (actions == ACTION_REPLACE_ALL) {
        check_argc(argc, 2, 3);
        value = normalize_value(argv[0], argv[1]);
        return git_config_set_multivar_in_file(given_config_file,
                                               argv[0], value, argv[2], 1);
    }
    else if (actions == ACTION_GET) {
        check_argc(argc, 1, 2);
        return get_value(argv[0], argv[1]);
    }
    else if (actions == ACTION_GET_ALL) {
        do_all = 1;
        check_argc(argc, 1, 2);
        return get_value(argv[0], argv[1]);
    }
    else if (actions == ACTION_GET_REGEXP) {
        show_keys = 1;
        use_key_regexp = 1;
        do_all = 1;
        check_argc(argc, 1, 2);
        return get_value(argv[0], argv[1]);
    }
    else if (actions == ACTION_UNSET) {
        check_argc(argc, 1, 2);
        if (argc == 2)
            return git_config_set_multivar_in_file(given_config_file,
                                                   argv[0], NULL, argv[1], 0);
        else
            return git_config_set_in_file(given_config_file,
                                          argv[0], NULL);
    }
    else if (actions == ACTION_UNSET_ALL) {
        check_argc(argc, 1, 2);
        return git_config_set_multivar_in_file(given_config_file,
                                               argv[0], NULL, argv[1], 1);
    }
    else if (actions == ACTION_RENAME_SECTION) {
        int ret;
        check_argc(argc, 2, 2);
        ret = git_config_rename_section_in_file(given_config_file,
                                                argv[0], argv[1]);
        if (ret < 0)
            return ret;
        if (ret == 0)
            die("No such section!");
    }
    else if (actions == ACTION_REMOVE_SECTION) {
        int ret;
        check_argc(argc, 1, 1);
        ret = git_config_rename_section_in_file(given_config_file,
                                                argv[0], NULL);
        if (ret < 0)
            return ret;
        if (ret == 0)
            die("No such section!");
    }
    else if (actions == ACTION_GET_COLOR) {
        get_color(argv[0]);
    }
    else if (actions == ACTION_GET_COLORBOOL) {
        if (argc == 1)
            color_stdout_is_tty = git_config_bool("command line", argv[0]);
        return get_colorbool(argc != 0);
    }

    return 0;
}
Ejemplo n.º 7
0
static int module_clone(int argc, const char **argv, const char *prefix)
{
	const char *path = NULL, *name = NULL, *url = NULL;
	const char *reference = NULL, *depth = NULL;
	int quiet = 0;
	FILE *submodule_dot_git;
	char *sm_gitdir, *cwd, *p;
	struct strbuf rel_path = STRBUF_INIT;
	struct strbuf sb = STRBUF_INIT;

	struct option module_clone_options[] = {
		OPT_STRING(0, "prefix", &prefix,
			   N_("path"),
			   N_("alternative anchor for relative paths")),
		OPT_STRING(0, "path", &path,
			   N_("path"),
			   N_("where the new submodule will be cloned to")),
		OPT_STRING(0, "name", &name,
			   N_("string"),
			   N_("name of the new submodule")),
		OPT_STRING(0, "url", &url,
			   N_("string"),
			   N_("url where to clone the submodule from")),
		OPT_STRING(0, "reference", &reference,
			   N_("string"),
			   N_("reference repository")),
		OPT_STRING(0, "depth", &depth,
			   N_("string"),
			   N_("depth for shallow clones")),
		OPT__QUIET(&quiet, "Suppress output for cloning a submodule"),
		OPT_END()
	};

	const char *const git_submodule_helper_usage[] = {
		N_("git submodule--helper clone [--prefix=<path>] [--quiet] "
		   "[--reference <repository>] [--name <name>] [--url <url>]"
		   "[--depth <depth>] [--] [<path>...]"),
		NULL
	};

	argc = parse_options(argc, argv, prefix, module_clone_options,
			     git_submodule_helper_usage, 0);

	strbuf_addf(&sb, "%s/modules/%s", get_git_dir(), name);
	sm_gitdir = strbuf_detach(&sb, NULL);

	if (!file_exists(sm_gitdir)) {
		if (safe_create_leading_directories_const(sm_gitdir) < 0)
			die(_("could not create directory '%s'"), sm_gitdir);
		if (clone_submodule(path, sm_gitdir, url, depth, reference, quiet))
			die(_("clone of '%s' into submodule path '%s' failed"),
			    url, path);
	} else {
		if (safe_create_leading_directories_const(path) < 0)
			die(_("could not create directory '%s'"), path);
		strbuf_addf(&sb, "%s/index", sm_gitdir);
		unlink_or_warn(sb.buf);
		strbuf_reset(&sb);
	}

	/* Write a .git file in the submodule to redirect to the superproject. */
	if (safe_create_leading_directories_const(path) < 0)
		die(_("could not create directory '%s'"), path);

	if (path && *path)
		strbuf_addf(&sb, "%s/.git", path);
	else
		strbuf_addstr(&sb, ".git");

	if (safe_create_leading_directories_const(sb.buf) < 0)
		die(_("could not create leading directories of '%s'"), sb.buf);
	submodule_dot_git = fopen(sb.buf, "w");
	if (!submodule_dot_git)
		die_errno(_("cannot open file '%s'"), sb.buf);

	fprintf(submodule_dot_git, "gitdir: %s\n",
		relative_path(sm_gitdir, path, &rel_path));
	if (fclose(submodule_dot_git))
		die(_("could not close file %s"), sb.buf);
	strbuf_reset(&sb);
	strbuf_reset(&rel_path);

	cwd = xgetcwd();
	/* Redirect the worktree of the submodule in the superproject's config */
	if (!is_absolute_path(sm_gitdir)) {
		strbuf_addf(&sb, "%s/%s", cwd, sm_gitdir);
		free(sm_gitdir);
		sm_gitdir = strbuf_detach(&sb, NULL);
	}

	strbuf_addf(&sb, "%s/%s", cwd, path);
	p = git_pathdup_submodule(path, "config");
	if (!p)
		die(_("could not get submodule directory for '%s'"), path);
	git_config_set_in_file(p, "core.worktree",
			       relative_path(sb.buf, sm_gitdir, &rel_path));
	strbuf_release(&sb);
	strbuf_release(&rel_path);
	free(sm_gitdir);
	free(cwd);
	free(p);
	return 0;
}
Ejemplo n.º 8
0
static int module_clone(int argc, const char **argv, const char *prefix)
{
	const char *name = NULL, *url = NULL, *depth = NULL;
	int quiet = 0;
	int progress = 0;
	char *p, *path = NULL, *sm_gitdir;
	struct strbuf sb = STRBUF_INIT;
	struct string_list reference = STRING_LIST_INIT_NODUP;
	char *sm_alternate = NULL, *error_strategy = NULL;

	struct option module_clone_options[] = {
		OPT_STRING(0, "prefix", &prefix,
			   N_("path"),
			   N_("alternative anchor for relative paths")),
		OPT_STRING(0, "path", &path,
			   N_("path"),
			   N_("where the new submodule will be cloned to")),
		OPT_STRING(0, "name", &name,
			   N_("string"),
			   N_("name of the new submodule")),
		OPT_STRING(0, "url", &url,
			   N_("string"),
			   N_("url where to clone the submodule from")),
		OPT_STRING_LIST(0, "reference", &reference,
			   N_("repo"),
			   N_("reference repository")),
		OPT_STRING(0, "depth", &depth,
			   N_("string"),
			   N_("depth for shallow clones")),
		OPT__QUIET(&quiet, "Suppress output for cloning a submodule"),
		OPT_BOOL(0, "progress", &progress,
			   N_("force cloning progress")),
		OPT_END()
	};

	const char *const git_submodule_helper_usage[] = {
		N_("git submodule--helper clone [--prefix=<path>] [--quiet] "
		   "[--reference <repository>] [--name <name>] [--depth <depth>] "
		   "--url <url> --path <path>"),
		NULL
	};

	argc = parse_options(argc, argv, prefix, module_clone_options,
			     git_submodule_helper_usage, 0);

	if (argc || !url || !path || !*path)
		usage_with_options(git_submodule_helper_usage,
				   module_clone_options);

	strbuf_addf(&sb, "%s/modules/%s", get_git_dir(), name);
	sm_gitdir = absolute_pathdup(sb.buf);
	strbuf_reset(&sb);

	if (!is_absolute_path(path)) {
		strbuf_addf(&sb, "%s/%s", get_git_work_tree(), path);
		path = strbuf_detach(&sb, NULL);
	} else
		path = xstrdup(path);

	if (!file_exists(sm_gitdir)) {
		if (safe_create_leading_directories_const(sm_gitdir) < 0)
			die(_("could not create directory '%s'"), sm_gitdir);

		prepare_possible_alternates(name, &reference);

		if (clone_submodule(path, sm_gitdir, url, depth, &reference,
				    quiet, progress))
			die(_("clone of '%s' into submodule path '%s' failed"),
			    url, path);
	} else {
		if (safe_create_leading_directories_const(path) < 0)
			die(_("could not create directory '%s'"), path);
		strbuf_addf(&sb, "%s/index", sm_gitdir);
		unlink_or_warn(sb.buf);
		strbuf_reset(&sb);
	}

	/* Connect module worktree and git dir */
	connect_work_tree_and_git_dir(path, sm_gitdir);

	p = git_pathdup_submodule(path, "config");
	if (!p)
		die(_("could not get submodule directory for '%s'"), path);

	/* setup alternateLocation and alternateErrorStrategy in the cloned submodule if needed */
	git_config_get_string("submodule.alternateLocation", &sm_alternate);
	if (sm_alternate)
		git_config_set_in_file(p, "submodule.alternateLocation",
					   sm_alternate);
	git_config_get_string("submodule.alternateErrorStrategy", &error_strategy);
	if (error_strategy)
		git_config_set_in_file(p, "submodule.alternateErrorStrategy",
					   error_strategy);

	free(sm_alternate);
	free(error_strategy);

	strbuf_release(&sb);
	free(sm_gitdir);
	free(path);
	free(p);
	return 0;
}