Blame advice.c

Packit Service fe3200
#include "cache.h"
Packit Service fe3200
#include "config.h"
Packit Service fe3200
#include "color.h"
Packit Service fe3200
#include "help.h"
Packit Service fe3200
Packit Service fe3200
int advice_fetch_show_forced_updates = 1;
Packit Service fe3200
int advice_push_update_rejected = 1;
Packit Service fe3200
int advice_push_non_ff_current = 1;
Packit Service fe3200
int advice_push_non_ff_matching = 1;
Packit Service fe3200
int advice_push_already_exists = 1;
Packit Service fe3200
int advice_push_fetch_first = 1;
Packit Service fe3200
int advice_push_needs_force = 1;
Packit Service fe3200
int advice_push_unqualified_ref_name = 1;
Packit Service fe3200
int advice_status_hints = 1;
Packit Service fe3200
int advice_status_u_option = 1;
Packit Service fe3200
int advice_status_ahead_behind_warning = 1;
Packit Service fe3200
int advice_commit_before_merge = 1;
Packit Service fe3200
int advice_reset_quiet_warning = 1;
Packit Service fe3200
int advice_resolve_conflict = 1;
Packit Service fe3200
int advice_sequencer_in_use = 1;
Packit Service fe3200
int advice_implicit_identity = 1;
Packit Service fe3200
int advice_detached_head = 1;
Packit Service fe3200
int advice_set_upstream_failure = 1;
Packit Service fe3200
int advice_object_name_warning = 1;
Packit Service fe3200
int advice_amworkdir = 1;
Packit Service fe3200
int advice_rm_hints = 1;
Packit Service fe3200
int advice_add_embedded_repo = 1;
Packit Service fe3200
int advice_ignored_hook = 1;
Packit Service fe3200
int advice_waiting_for_editor = 1;
Packit Service fe3200
int advice_graft_file_deprecated = 1;
Packit Service fe3200
int advice_checkout_ambiguous_remote_branch_name = 1;
Packit Service fe3200
int advice_submodule_alternate_error_strategy_die = 1;
Packit Service fe3200
int advice_add_ignored_file = 1;
Packit Service fe3200
int advice_add_empty_pathspec = 1;
Packit Service fe3200
Packit Service fe3200
static int advice_use_color = -1;
Packit Service fe3200
static char advice_colors[][COLOR_MAXLEN] = {
Packit Service fe3200
	GIT_COLOR_RESET,
Packit Service fe3200
	GIT_COLOR_YELLOW,	/* HINT */
Packit Service fe3200
};
Packit Service fe3200
Packit Service fe3200
enum color_advice {
Packit Service fe3200
	ADVICE_COLOR_RESET = 0,
Packit Service fe3200
	ADVICE_COLOR_HINT = 1,
Packit Service fe3200
};
Packit Service fe3200
Packit Service fe3200
static int parse_advise_color_slot(const char *slot)
Packit Service fe3200
{
Packit Service fe3200
	if (!strcasecmp(slot, "reset"))
Packit Service fe3200
		return ADVICE_COLOR_RESET;
Packit Service fe3200
	if (!strcasecmp(slot, "hint"))
Packit Service fe3200
		return ADVICE_COLOR_HINT;
Packit Service fe3200
	return -1;
Packit Service fe3200
}
Packit Service fe3200
Packit Service fe3200
static const char *advise_get_color(enum color_advice ix)
Packit Service fe3200
{
Packit Service fe3200
	if (want_color_stderr(advice_use_color))
Packit Service fe3200
		return advice_colors[ix];
Packit Service fe3200
	return "";
Packit Service fe3200
}
Packit Service fe3200
Packit Service fe3200
static struct {
Packit Service fe3200
	const char *name;
Packit Service fe3200
	int *preference;
Packit Service fe3200
} advice_config[] = {
Packit Service fe3200
	{ "fetchShowForcedUpdates", &advice_fetch_show_forced_updates },
Packit Service fe3200
	{ "pushUpdateRejected", &advice_push_update_rejected },
Packit Service fe3200
	{ "pushNonFFCurrent", &advice_push_non_ff_current },
Packit Service fe3200
	{ "pushNonFFMatching", &advice_push_non_ff_matching },
Packit Service fe3200
	{ "pushAlreadyExists", &advice_push_already_exists },
Packit Service fe3200
	{ "pushFetchFirst", &advice_push_fetch_first },
Packit Service fe3200
	{ "pushNeedsForce", &advice_push_needs_force },
Packit Service fe3200
	{ "pushUnqualifiedRefName", &advice_push_unqualified_ref_name },
Packit Service fe3200
	{ "statusHints", &advice_status_hints },
Packit Service fe3200
	{ "statusUoption", &advice_status_u_option },
Packit Service fe3200
	{ "statusAheadBehindWarning", &advice_status_ahead_behind_warning },
Packit Service fe3200
	{ "commitBeforeMerge", &advice_commit_before_merge },
Packit Service fe3200
	{ "resetQuiet", &advice_reset_quiet_warning },
Packit Service fe3200
	{ "resolveConflict", &advice_resolve_conflict },
Packit Service fe3200
	{ "sequencerInUse", &advice_sequencer_in_use },
Packit Service fe3200
	{ "implicitIdentity", &advice_implicit_identity },
Packit Service fe3200
	{ "detachedHead", &advice_detached_head },
Packit Service fe3200
	{ "setUpstreamFailure", &advice_set_upstream_failure },
Packit Service fe3200
	{ "objectNameWarning", &advice_object_name_warning },
Packit Service fe3200
	{ "amWorkDir", &advice_amworkdir },
Packit Service fe3200
	{ "rmHints", &advice_rm_hints },
Packit Service fe3200
	{ "addEmbeddedRepo", &advice_add_embedded_repo },
Packit Service fe3200
	{ "ignoredHook", &advice_ignored_hook },
Packit Service fe3200
	{ "waitingForEditor", &advice_waiting_for_editor },
Packit Service fe3200
	{ "graftFileDeprecated", &advice_graft_file_deprecated },
Packit Service fe3200
	{ "checkoutAmbiguousRemoteBranchName", &advice_checkout_ambiguous_remote_branch_name },
Packit Service fe3200
	{ "submoduleAlternateErrorStrategyDie", &advice_submodule_alternate_error_strategy_die },
Packit Service fe3200
	{ "addIgnoredFile", &advice_add_ignored_file },
Packit Service fe3200
	{ "addEmptyPathspec", &advice_add_empty_pathspec },
Packit Service fe3200
Packit Service fe3200
	/* make this an alias for backward compatibility */
Packit Service fe3200
	{ "pushNonFastForward", &advice_push_update_rejected }
Packit Service fe3200
};
Packit Service fe3200
Packit Service fe3200
static struct {
Packit Service fe3200
	const char *key;
Packit Service fe3200
	int enabled;
Packit Service fe3200
} advice_setting[] = {
Packit Service fe3200
	[ADVICE_ADD_EMBEDDED_REPO]			= { "addEmbeddedRepo", 1 },
Packit Service fe3200
	[ADVICE_AM_WORK_DIR] 				= { "amWorkDir", 1 },
Packit Service fe3200
	[ADVICE_CHECKOUT_AMBIGUOUS_REMOTE_BRANCH_NAME] 	= { "checkoutAmbiguousRemoteBranchName", 1 },
Packit Service fe3200
	[ADVICE_COMMIT_BEFORE_MERGE]			= { "commitBeforeMerge", 1 },
Packit Service fe3200
	[ADVICE_DETACHED_HEAD]				= { "detachedHead", 1 },
Packit Service fe3200
	[ADVICE_FETCH_SHOW_FORCED_UPDATES]		= { "fetchShowForcedUpdates", 1 },
Packit Service fe3200
	[ADVICE_GRAFT_FILE_DEPRECATED]			= { "graftFileDeprecated", 1 },
Packit Service fe3200
	[ADVICE_IGNORED_HOOK]				= { "ignoredHook", 1 },
Packit Service fe3200
	[ADVICE_IMPLICIT_IDENTITY]			= { "implicitIdentity", 1 },
Packit Service fe3200
	[ADVICE_NESTED_TAG]				= { "nestedTag", 1 },
Packit Service fe3200
	[ADVICE_OBJECT_NAME_WARNING]			= { "objectNameWarning", 1 },
Packit Service fe3200
	[ADVICE_PUSH_ALREADY_EXISTS]			= { "pushAlreadyExists", 1 },
Packit Service fe3200
	[ADVICE_PUSH_FETCH_FIRST]			= { "pushFetchFirst", 1 },
Packit Service fe3200
	[ADVICE_PUSH_NEEDS_FORCE]			= { "pushNeedsForce", 1 },
Packit Service fe3200
Packit Service fe3200
	/* make this an alias for backward compatibility */
Packit Service fe3200
	[ADVICE_PUSH_UPDATE_REJECTED_ALIAS]		= { "pushNonFastForward", 1 },
Packit Service fe3200
Packit Service fe3200
	[ADVICE_PUSH_NON_FF_CURRENT]			= { "pushNonFFCurrent", 1 },
Packit Service fe3200
	[ADVICE_PUSH_NON_FF_MATCHING]			= { "pushNonFFMatching", 1 },
Packit Service fe3200
	[ADVICE_PUSH_UNQUALIFIED_REF_NAME]		= { "pushUnqualifiedRefName", 1 },
Packit Service fe3200
	[ADVICE_PUSH_UPDATE_REJECTED]			= { "pushUpdateRejected", 1 },
Packit Service fe3200
	[ADVICE_RESET_QUIET_WARNING]			= { "resetQuiet", 1 },
Packit Service fe3200
	[ADVICE_RESOLVE_CONFLICT]			= { "resolveConflict", 1 },
Packit Service fe3200
	[ADVICE_RM_HINTS]				= { "rmHints", 1 },
Packit Service fe3200
	[ADVICE_SEQUENCER_IN_USE]			= { "sequencerInUse", 1 },
Packit Service fe3200
	[ADVICE_SET_UPSTREAM_FAILURE]			= { "setUpstreamFailure", 1 },
Packit Service fe3200
	[ADVICE_STATUS_AHEAD_BEHIND_WARNING]		= { "statusAheadBehindWarning", 1 },
Packit Service fe3200
	[ADVICE_STATUS_HINTS]				= { "statusHints", 1 },
Packit Service fe3200
	[ADVICE_STATUS_U_OPTION]			= { "statusUoption", 1 },
Packit Service fe3200
	[ADVICE_SUBMODULE_ALTERNATE_ERROR_STRATEGY_DIE] = { "submoduleAlternateErrorStrategyDie", 1 },
Packit Service fe3200
	[ADVICE_WAITING_FOR_EDITOR]			= { "waitingForEditor", 1 },
Packit Service fe3200
};
Packit Service fe3200
Packit Service fe3200
static const char turn_off_instructions[] =
Packit Service fe3200
N_("\n"
Packit Service fe3200
   "Disable this message with \"git config advice.%s false\"");
Packit Service fe3200
Packit Service fe3200
static void vadvise(const char *advice, int display_instructions,
Packit Service fe3200
		    const char *key, va_list params)
Packit Service fe3200
{
Packit Service fe3200
	struct strbuf buf = STRBUF_INIT;
Packit Service fe3200
	const char *cp, *np;
Packit Service fe3200
Packit Service fe3200
	strbuf_vaddf(&buf, advice, params);
Packit Service fe3200
Packit Service fe3200
	if (display_instructions)
Packit Service fe3200
		strbuf_addf(&buf, turn_off_instructions, key);
Packit Service fe3200
Packit Service fe3200
	for (cp = buf.buf; *cp; cp = np) {
Packit Service fe3200
		np = strchrnul(cp, '\n');
Packit Service fe3200
		fprintf(stderr,	_("%shint: %.*s%s\n"),
Packit Service fe3200
			advise_get_color(ADVICE_COLOR_HINT),
Packit Service fe3200
			(int)(np - cp), cp,
Packit Service fe3200
			advise_get_color(ADVICE_COLOR_RESET));
Packit Service fe3200
		if (*np)
Packit Service fe3200
			np++;
Packit Service fe3200
	}
Packit Service fe3200
	strbuf_release(&buf;;
Packit Service fe3200
}
Packit Service fe3200
Packit Service fe3200
void advise(const char *advice, ...)
Packit Service fe3200
{
Packit Service fe3200
	va_list params;
Packit Service fe3200
	va_start(params, advice);
Packit Service fe3200
	vadvise(advice, 0, "", params);
Packit Service fe3200
	va_end(params);
Packit Service fe3200
}
Packit Service fe3200
Packit Service fe3200
int advice_enabled(enum advice_type type)
Packit Service fe3200
{
Packit Service fe3200
	switch(type) {
Packit Service fe3200
	case ADVICE_PUSH_UPDATE_REJECTED:
Packit Service fe3200
		return advice_setting[ADVICE_PUSH_UPDATE_REJECTED].enabled &&
Packit Service fe3200
		       advice_setting[ADVICE_PUSH_UPDATE_REJECTED_ALIAS].enabled;
Packit Service fe3200
	default:
Packit Service fe3200
		return advice_setting[type].enabled;
Packit Service fe3200
	}
Packit Service fe3200
}
Packit Service fe3200
Packit Service fe3200
void advise_if_enabled(enum advice_type type, const char *advice, ...)
Packit Service fe3200
{
Packit Service fe3200
	va_list params;
Packit Service fe3200
Packit Service fe3200
	if (!advice_enabled(type))
Packit Service fe3200
		return;
Packit Service fe3200
Packit Service fe3200
	va_start(params, advice);
Packit Service fe3200
	vadvise(advice, 1, advice_setting[type].key, params);
Packit Service fe3200
	va_end(params);
Packit Service fe3200
}
Packit Service fe3200
Packit Service fe3200
int git_default_advice_config(const char *var, const char *value)
Packit Service fe3200
{
Packit Service fe3200
	const char *k, *slot_name;
Packit Service fe3200
	int i;
Packit Service fe3200
Packit Service fe3200
	if (!strcmp(var, "color.advice")) {
Packit Service fe3200
		advice_use_color = git_config_colorbool(var, value);
Packit Service fe3200
		return 0;
Packit Service fe3200
	}
Packit Service fe3200
Packit Service fe3200
	if (skip_prefix(var, "color.advice.", &slot_name)) {
Packit Service fe3200
		int slot = parse_advise_color_slot(slot_name);
Packit Service fe3200
		if (slot < 0)
Packit Service fe3200
			return 0;
Packit Service fe3200
		if (!value)
Packit Service fe3200
			return config_error_nonbool(var);
Packit Service fe3200
		return color_parse(value, advice_colors[slot]);
Packit Service fe3200
	}
Packit Service fe3200
Packit Service fe3200
	if (!skip_prefix(var, "advice.", &k))
Packit Service fe3200
		return 0;
Packit Service fe3200
Packit Service fe3200
	for (i = 0; i < ARRAY_SIZE(advice_config); i++) {
Packit Service fe3200
		if (strcasecmp(k, advice_config[i].name))
Packit Service fe3200
			continue;
Packit Service fe3200
		*advice_config[i].preference = git_config_bool(var, value);
Packit Service fe3200
		break;
Packit Service fe3200
	}
Packit Service fe3200
Packit Service fe3200
	for (i = 0; i < ARRAY_SIZE(advice_setting); i++) {
Packit Service fe3200
		if (strcasecmp(k, advice_setting[i].key))
Packit Service fe3200
			continue;
Packit Service fe3200
		advice_setting[i].enabled = git_config_bool(var, value);
Packit Service fe3200
		return 0;
Packit Service fe3200
	}
Packit Service fe3200
Packit Service fe3200
	return 0;
Packit Service fe3200
}
Packit Service fe3200
Packit Service fe3200
void list_config_advices(struct string_list *list, const char *prefix)
Packit Service fe3200
{
Packit Service fe3200
	int i;
Packit Service fe3200
Packit Service fe3200
	for (i = 0; i < ARRAY_SIZE(advice_setting); i++)
Packit Service fe3200
		list_config_item(list, prefix, advice_setting[i].key);
Packit Service fe3200
}
Packit Service fe3200
Packit Service fe3200
int error_resolve_conflict(const char *me)
Packit Service fe3200
{
Packit Service fe3200
	if (!strcmp(me, "cherry-pick"))
Packit Service fe3200
		error(_("Cherry-picking is not possible because you have unmerged files."));
Packit Service fe3200
	else if (!strcmp(me, "commit"))
Packit Service fe3200
		error(_("Committing is not possible because you have unmerged files."));
Packit Service fe3200
	else if (!strcmp(me, "merge"))
Packit Service fe3200
		error(_("Merging is not possible because you have unmerged files."));
Packit Service fe3200
	else if (!strcmp(me, "pull"))
Packit Service fe3200
		error(_("Pulling is not possible because you have unmerged files."));
Packit Service fe3200
	else if (!strcmp(me, "revert"))
Packit Service fe3200
		error(_("Reverting is not possible because you have unmerged files."));
Packit Service fe3200
	else
Packit Service fe3200
		error(_("It is not possible to %s because you have unmerged files."),
Packit Service fe3200
			me);
Packit Service fe3200
Packit Service fe3200
	if (advice_resolve_conflict)
Packit Service fe3200
		/*
Packit Service fe3200
		 * Message used both when 'git commit' fails and when
Packit Service fe3200
		 * other commands doing a merge do.
Packit Service fe3200
		 */
Packit Service fe3200
		advise(_("Fix them up in the work tree, and then use 'git add/rm <file>'\n"
Packit Service fe3200
			 "as appropriate to mark resolution and make a commit."));
Packit Service fe3200
	return -1;
Packit Service fe3200
}
Packit Service fe3200
Packit Service fe3200
void NORETURN die_resolve_conflict(const char *me)
Packit Service fe3200
{
Packit Service fe3200
	error_resolve_conflict(me);
Packit Service fe3200
	die(_("Exiting because of an unresolved conflict."));
Packit Service fe3200
}
Packit Service fe3200
Packit Service fe3200
void NORETURN die_conclude_merge(void)
Packit Service fe3200
{
Packit Service fe3200
	error(_("You have not concluded your merge (MERGE_HEAD exists)."));
Packit Service fe3200
	if (advice_resolve_conflict)
Packit Service fe3200
		advise(_("Please, commit your changes before merging."));
Packit Service fe3200
	die(_("Exiting because of unfinished merge."));
Packit Service fe3200
}
Packit Service fe3200
Packit Service fe3200
void detach_advice(const char *new_name)
Packit Service fe3200
{
Packit Service fe3200
	const char *fmt =
Packit Service fe3200
	_("Note: switching to '%s'.\n"
Packit Service fe3200
	"\n"
Packit Service fe3200
	"You are in 'detached HEAD' state. You can look around, make experimental\n"
Packit Service fe3200
	"changes and commit them, and you can discard any commits you make in this\n"
Packit Service fe3200
	"state without impacting any branches by switching back to a branch.\n"
Packit Service fe3200
	"\n"
Packit Service fe3200
	"If you want to create a new branch to retain commits you create, you may\n"
Packit Service fe3200
	"do so (now or later) by using -c with the switch command. Example:\n"
Packit Service fe3200
	"\n"
Packit Service fe3200
	"  git switch -c <new-branch-name>\n"
Packit Service fe3200
	"\n"
Packit Service fe3200
	"Or undo this operation with:\n"
Packit Service fe3200
	"\n"
Packit Service fe3200
	"  git switch -\n"
Packit Service fe3200
	"\n"
Packit Service fe3200
	"Turn off this advice by setting config variable advice.detachedHead to false\n\n");
Packit Service fe3200
Packit Service fe3200
	fprintf(stderr, fmt, new_name);
Packit Service fe3200
}