static int diff_generated_apply_options()

in src/diff_generate.c [443:556]


static int diff_generated_apply_options(
	git_diff_generated *diff,
	const git_diff_options *opts)
{
	git_config *cfg = NULL;
	git_repository *repo = diff->base.repo;
	git_pool *pool = &diff->base.pool;
	int val;

	if (opts) {
		/* copy user options (except case sensitivity info from iterators) */
		bool icase = DIFF_FLAG_IS_SET(diff, GIT_DIFF_IGNORE_CASE);
		memcpy(&diff->base.opts, opts, sizeof(diff->base.opts));
		DIFF_FLAG_SET(diff, GIT_DIFF_IGNORE_CASE, icase);

		/* initialize pathspec from options */
		if (git_pathspec__vinit(&diff->pathspec, &opts->pathspec, pool) < 0)
			return -1;
	}

	/* flag INCLUDE_TYPECHANGE_TREES implies INCLUDE_TYPECHANGE */
	if (DIFF_FLAG_IS_SET(diff, GIT_DIFF_INCLUDE_TYPECHANGE_TREES))
		diff->base.opts.flags |= GIT_DIFF_INCLUDE_TYPECHANGE;

	/* flag INCLUDE_UNTRACKED_CONTENT implies INCLUDE_UNTRACKED */
	if (DIFF_FLAG_IS_SET(diff, GIT_DIFF_SHOW_UNTRACKED_CONTENT))
		diff->base.opts.flags |= GIT_DIFF_INCLUDE_UNTRACKED;

	/* load config values that affect diff behavior */
	if ((val = git_repository_config_snapshot(&cfg, repo)) < 0)
		return val;

	if (!git_config__configmap_lookup(&val, cfg, GIT_CONFIGMAP_SYMLINKS) && val)
		diff->diffcaps |= GIT_DIFFCAPS_HAS_SYMLINKS;

	if (!git_config__configmap_lookup(&val, cfg, GIT_CONFIGMAP_IGNORESTAT) && val)
		diff->diffcaps |= GIT_DIFFCAPS_IGNORE_STAT;

	if ((diff->base.opts.flags & GIT_DIFF_IGNORE_FILEMODE) == 0 &&
		!git_config__configmap_lookup(&val, cfg, GIT_CONFIGMAP_FILEMODE) && val)
		diff->diffcaps |= GIT_DIFFCAPS_TRUST_MODE_BITS;

	if (!git_config__configmap_lookup(&val, cfg, GIT_CONFIGMAP_TRUSTCTIME) && val)
		diff->diffcaps |= GIT_DIFFCAPS_TRUST_CTIME;

	/* Don't set GIT_DIFFCAPS_USE_DEV - compile time option in core git */

	/* If not given explicit `opts`, check `diff.xyz` configs */
	if (!opts) {
		int context = git_config__get_int_force(cfg, "diff.context", 3);
		diff->base.opts.context_lines = context >= 0 ? (uint32_t)context : 3;

		/* add other defaults here */
	}

	/* Reverse src info if diff is reversed */
	if (DIFF_FLAG_IS_SET(diff, GIT_DIFF_REVERSE)) {
		git_iterator_t tmp_src = diff->base.old_src;
		diff->base.old_src = diff->base.new_src;
		diff->base.new_src = tmp_src;
	}

	/* Unset UPDATE_INDEX unless diffing workdir and index */
	if (DIFF_FLAG_IS_SET(diff, GIT_DIFF_UPDATE_INDEX) &&
		(!(diff->base.old_src == GIT_ITERATOR_WORKDIR ||
		   diff->base.new_src == GIT_ITERATOR_WORKDIR) ||
		 !(diff->base.old_src == GIT_ITERATOR_INDEX ||
		   diff->base.new_src == GIT_ITERATOR_INDEX)))
		diff->base.opts.flags &= ~GIT_DIFF_UPDATE_INDEX;

	/* if ignore_submodules not explicitly set, check diff config */
	if (diff->base.opts.ignore_submodules <= 0) {
		 git_config_entry *entry;
		git_config__lookup_entry(&entry, cfg, "diff.ignoresubmodules", true);

		if (entry && git_submodule_parse_ignore(
				&diff->base.opts.ignore_submodules, entry->value) < 0)
			git_error_clear();
		git_config_entry_free(entry);
	}

	/* if either prefix is not set, figure out appropriate value */
	if (!diff->base.opts.old_prefix || !diff->base.opts.new_prefix) {
		const char *use_old = DIFF_OLD_PREFIX_DEFAULT;
		const char *use_new = DIFF_NEW_PREFIX_DEFAULT;

		if (git_config__get_bool_force(cfg, "diff.noprefix", 0))
			use_old = use_new = "";
		else if (git_config__get_bool_force(cfg, "diff.mnemonicprefix", 0)) {
			use_old = diff_mnemonic_prefix(diff->base.old_src, true);
			use_new = diff_mnemonic_prefix(diff->base.new_src, false);
		}

		if (!diff->base.opts.old_prefix)
			diff->base.opts.old_prefix = use_old;
		if (!diff->base.opts.new_prefix)
			diff->base.opts.new_prefix = use_new;
	}

	/* strdup prefix from pool so we're not dependent on external data */
	diff->base.opts.old_prefix = diff_strdup_prefix(pool, diff->base.opts.old_prefix);
	diff->base.opts.new_prefix = diff_strdup_prefix(pool, diff->base.opts.new_prefix);

	if (DIFF_FLAG_IS_SET(diff, GIT_DIFF_REVERSE)) {
		const char *tmp_prefix = diff->base.opts.old_prefix;
		diff->base.opts.old_prefix  = diff->base.opts.new_prefix;
		diff->base.opts.new_prefix  = tmp_prefix;
	}

	git_config_free(cfg);

	/* check strdup results for error */
	return (!diff->base.opts.old_prefix || !diff->base.opts.new_prefix) ? -1 : 0;
}