1#include "cache.h"2#include "lockfile.h"3#include "apply.h"45static void git_apply_config(void)6{7git_config_get_string_const("apply.whitespace", &apply_default_whitespace);8git_config_get_string_const("apply.ignorewhitespace", &apply_default_ignorewhitespace);9git_config(git_default_config, NULL);10}1112int parse_whitespace_option(struct apply_state *state, const char *option)13{14if (!option) {15state->ws_error_action = warn_on_ws_error;16return 0;17}18if (!strcmp(option, "warn")) {19state->ws_error_action = warn_on_ws_error;20return 0;21}22if (!strcmp(option, "nowarn")) {23state->ws_error_action = nowarn_ws_error;24return 0;25}26if (!strcmp(option, "error")) {27state->ws_error_action = die_on_ws_error;28return 0;29}30if (!strcmp(option, "error-all")) {31state->ws_error_action = die_on_ws_error;32state->squelch_whitespace_errors = 0;33return 0;34}35if (!strcmp(option, "strip") || !strcmp(option, "fix")) {36state->ws_error_action = correct_ws_error;37return 0;38}39return error(_("unrecognized whitespace option '%s'"), option);40}4142int parse_ignorewhitespace_option(struct apply_state *state,43const char *option)44{45if (!option || !strcmp(option, "no") ||46!strcmp(option, "false") || !strcmp(option, "never") ||47!strcmp(option, "none")) {48state->ws_ignore_action = ignore_ws_none;49return 0;50}51if (!strcmp(option, "change")) {52state->ws_ignore_action = ignore_ws_change;53return 0;54}55return error(_("unrecognized whitespace ignore option '%s'"), option);56}5758int init_apply_state(struct apply_state *state,59const char *prefix,60struct lock_file *lock_file)61{62memset(state, 0, sizeof(*state));63state->prefix = prefix;64state->prefix_length = state->prefix ? strlen(state->prefix) : 0;65state->lock_file = lock_file;66state->newfd = -1;67state->apply = 1;68state->line_termination = '\n';69state->p_value = 1;70state->p_context = UINT_MAX;71state->squelch_whitespace_errors = 5;72state->ws_error_action = warn_on_ws_error;73state->ws_ignore_action = ignore_ws_none;74state->linenr = 1;75string_list_init(&state->fn_table, 0);76string_list_init(&state->limit_by_name, 0);77string_list_init(&state->symlink_changes, 0);78strbuf_init(&state->root, 0);7980git_apply_config();81if (apply_default_whitespace && parse_whitespace_option(state, apply_default_whitespace))82return -1;83if (apply_default_ignorewhitespace && parse_ignorewhitespace_option(state, apply_default_ignorewhitespace))84return -1;85return 0;86}8788void clear_apply_state(struct apply_state *state)89{90string_list_clear(&state->limit_by_name, 0);91string_list_clear(&state->symlink_changes, 0);92strbuf_release(&state->root);9394/* &state->fn_table is cleared at the end of apply_patch() */95}9697int check_apply_state(struct apply_state *state, int force_apply)98{99int is_not_gitdir = !startup_info->have_repository;100101if (state->apply_with_reject && state->threeway)102return error("--reject and --3way cannot be used together.");103if (state->cached && state->threeway)104return error("--cached and --3way cannot be used together.");105if (state->threeway) {106if (is_not_gitdir)107return error(_("--3way outside a repository"));108state->check_index = 1;109}110if (state->apply_with_reject)111state->apply = state->apply_verbosely = 1;112if (!force_apply && (state->diffstat || state->numstat || state->summary || state->check || state->fake_ancestor))113state->apply = 0;114if (state->check_index && is_not_gitdir)115return error(_("--index outside a repository"));116if (state->cached) {117if (is_not_gitdir)118return error(_("--cached outside a repository"));119state->check_index = 1;120}121if (state->check_index)122state->unsafe_paths = 0;123if (!state->lock_file)124return error("BUG: state->lock_file should not be NULL");125126return 0;127}