blob: 6fda9edbc2474fe15c128014b99660034d269177 [file] [log] [blame]
Jeff King75194432009-09-09 07:38:58 -04001#include "cache.h"
Brandon Williamsb2141fc2017-06-14 11:07:36 -07002#include "config.h"
Ryan Dammrose960786e2018-04-21 12:10:00 +02003#include "color.h"
Nguyễn Thái Ngọc Duy3ac68a92018-05-26 15:55:24 +02004#include "help.h"
Matheus Tavaresa20f7042021-04-08 17:41:27 -03005#include "string-list.h"
Jeff King75194432009-09-09 07:38:58 -04006
Ryan Dammrose960786e2018-04-21 12:10:00 +02007static int advice_use_color = -1;
8static char advice_colors[][COLOR_MAXLEN] = {
9 GIT_COLOR_RESET,
10 GIT_COLOR_YELLOW, /* HINT */
11};
12
13enum color_advice {
14 ADVICE_COLOR_RESET = 0,
15 ADVICE_COLOR_HINT = 1,
16};
17
18static int parse_advise_color_slot(const char *slot)
19{
20 if (!strcasecmp(slot, "reset"))
21 return ADVICE_COLOR_RESET;
22 if (!strcasecmp(slot, "hint"))
23 return ADVICE_COLOR_HINT;
24 return -1;
25}
26
27static const char *advise_get_color(enum color_advice ix)
28{
29 if (want_color_stderr(advice_use_color))
30 return advice_colors[ix];
31 return "";
32}
33
Jeff King75194432009-09-09 07:38:58 -040034static struct {
Heba Walyb3b18d12020-03-02 20:01:59 +000035 const char *key;
36 int enabled;
37} advice_setting[] = {
38 [ADVICE_ADD_EMBEDDED_REPO] = { "addEmbeddedRepo", 1 },
Ben Boeckel69290552021-08-23 12:43:59 +020039 [ADVICE_ADD_EMPTY_PATHSPEC] = { "addEmptyPathspec", 1 },
40 [ADVICE_ADD_IGNORED_FILE] = { "addIgnoredFile", 1 },
Heba Walyb3b18d12020-03-02 20:01:59 +000041 [ADVICE_AM_WORK_DIR] = { "amWorkDir", 1 },
Tao Klerkse4921d82022-04-01 06:05:13 +000042 [ADVICE_AMBIGUOUS_FETCH_REFSPEC] = { "ambiguousFetchRefspec", 1 },
Heba Walyb3b18d12020-03-02 20:01:59 +000043 [ADVICE_CHECKOUT_AMBIGUOUS_REMOTE_BRANCH_NAME] = { "checkoutAmbiguousRemoteBranchName", 1 },
44 [ADVICE_COMMIT_BEFORE_MERGE] = { "commitBeforeMerge", 1 },
45 [ADVICE_DETACHED_HEAD] = { "detachedHead", 1 },
Alex Henrie808213b2022-02-25 23:12:13 -070046 [ADVICE_SUGGEST_DETACHING_HEAD] = { "suggestDetachingHead", 1 },
Heba Walyb3b18d12020-03-02 20:01:59 +000047 [ADVICE_FETCH_SHOW_FORCED_UPDATES] = { "fetchShowForcedUpdates", 1 },
48 [ADVICE_GRAFT_FILE_DEPRECATED] = { "graftFileDeprecated", 1 },
49 [ADVICE_IGNORED_HOOK] = { "ignoredHook", 1 },
50 [ADVICE_IMPLICIT_IDENTITY] = { "implicitIdentity", 1 },
51 [ADVICE_NESTED_TAG] = { "nestedTag", 1 },
52 [ADVICE_OBJECT_NAME_WARNING] = { "objectNameWarning", 1 },
53 [ADVICE_PUSH_ALREADY_EXISTS] = { "pushAlreadyExists", 1 },
54 [ADVICE_PUSH_FETCH_FIRST] = { "pushFetchFirst", 1 },
55 [ADVICE_PUSH_NEEDS_FORCE] = { "pushNeedsForce", 1 },
Srinidhi Kaushik3b990aa2020-10-03 17:40:45 +053056 [ADVICE_PUSH_REF_NEEDS_UPDATE] = { "pushRefNeedsUpdate", 1 },
Heba Walyb3b18d12020-03-02 20:01:59 +000057
58 /* make this an alias for backward compatibility */
59 [ADVICE_PUSH_UPDATE_REJECTED_ALIAS] = { "pushNonFastForward", 1 },
60
61 [ADVICE_PUSH_NON_FF_CURRENT] = { "pushNonFFCurrent", 1 },
62 [ADVICE_PUSH_NON_FF_MATCHING] = { "pushNonFFMatching", 1 },
63 [ADVICE_PUSH_UNQUALIFIED_REF_NAME] = { "pushUnqualifiedRefName", 1 },
64 [ADVICE_PUSH_UPDATE_REJECTED] = { "pushUpdateRejected", 1 },
Victoria Dye93962512022-03-15 01:49:40 +000065 [ADVICE_RESET_NO_REFRESH_WARNING] = { "resetNoRefresh", 1 },
Heba Walyb3b18d12020-03-02 20:01:59 +000066 [ADVICE_RESOLVE_CONFLICT] = { "resolveConflict", 1 },
67 [ADVICE_RM_HINTS] = { "rmHints", 1 },
68 [ADVICE_SEQUENCER_IN_USE] = { "sequencerInUse", 1 },
69 [ADVICE_SET_UPSTREAM_FAILURE] = { "setUpstreamFailure", 1 },
Josh Steadmon767a4ca2021-08-30 14:46:02 -070070 [ADVICE_SKIPPED_CHERRY_PICKS] = { "skippedCherryPicks", 1 },
Heba Walyb3b18d12020-03-02 20:01:59 +000071 [ADVICE_STATUS_AHEAD_BEHIND_WARNING] = { "statusAheadBehindWarning", 1 },
72 [ADVICE_STATUS_HINTS] = { "statusHints", 1 },
73 [ADVICE_STATUS_U_OPTION] = { "statusUoption", 1 },
74 [ADVICE_SUBMODULE_ALTERNATE_ERROR_STRATEGY_DIE] = { "submoduleAlternateErrorStrategyDie", 1 },
Glen Choo961b1302022-01-28 16:04:45 -080075 [ADVICE_SUBMODULES_NOT_UPDATED] = { "submodulesNotUpdated", 1 },
Matheus Tavaresa20f7042021-04-08 17:41:27 -030076 [ADVICE_UPDATE_SPARSE_PATH] = { "updateSparsePath", 1 },
Heba Walyb3b18d12020-03-02 20:01:59 +000077 [ADVICE_WAITING_FOR_EDITOR] = { "waitingForEditor", 1 },
78};
79
80static const char turn_off_instructions[] =
81N_("\n"
82 "Disable this message with \"git config advice.%s false\"");
83
84static void vadvise(const char *advice, int display_instructions,
85 const char *key, va_list params)
Ramkumar Ramachandra38ef61c2011-08-04 16:08:59 +053086{
Junio C Hamano23cb5bf2011-12-22 11:21:26 -080087 struct strbuf buf = STRBUF_INIT;
Junio C Hamano23cb5bf2011-12-22 11:21:26 -080088 const char *cp, *np;
Ramkumar Ramachandra38ef61c2011-08-04 16:08:59 +053089
Jeff King447b99c2012-07-23 14:48:57 -040090 strbuf_vaddf(&buf, advice, params);
Junio C Hamano23cb5bf2011-12-22 11:21:26 -080091
Heba Walyb3b18d12020-03-02 20:01:59 +000092 if (display_instructions)
93 strbuf_addf(&buf, turn_off_instructions, key);
Junio C Hamano23cb5bf2011-12-22 11:21:26 -080094
95 for (cp = buf.buf; *cp; cp = np) {
96 np = strchrnul(cp, '\n');
Ryan Dammrose960786e2018-04-21 12:10:00 +020097 fprintf(stderr, _("%shint: %.*s%s\n"),
98 advise_get_color(ADVICE_COLOR_HINT),
99 (int)(np - cp), cp,
100 advise_get_color(ADVICE_COLOR_RESET));
Junio C Hamano23cb5bf2011-12-22 11:21:26 -0800101 if (*np)
102 np++;
103 }
104 strbuf_release(&buf);
Ramkumar Ramachandra38ef61c2011-08-04 16:08:59 +0530105}
106
Heba Waly06ac2b32020-03-02 20:01:57 +0000107void advise(const char *advice, ...)
108{
109 va_list params;
110 va_start(params, advice);
Heba Walyb3b18d12020-03-02 20:01:59 +0000111 vadvise(advice, 0, "", params);
112 va_end(params);
113}
114
115int advice_enabled(enum advice_type type)
116{
117 switch(type) {
118 case ADVICE_PUSH_UPDATE_REJECTED:
119 return advice_setting[ADVICE_PUSH_UPDATE_REJECTED].enabled &&
120 advice_setting[ADVICE_PUSH_UPDATE_REJECTED_ALIAS].enabled;
121 default:
122 return advice_setting[type].enabled;
123 }
124}
125
126void advise_if_enabled(enum advice_type type, const char *advice, ...)
127{
128 va_list params;
129
130 if (!advice_enabled(type))
131 return;
132
133 va_start(params, advice);
134 vadvise(advice, 1, advice_setting[type].key, params);
Heba Waly06ac2b32020-03-02 20:01:57 +0000135 va_end(params);
136}
137
Jeff King75194432009-09-09 07:38:58 -0400138int git_default_advice_config(const char *var, const char *value)
139{
Ryan Dammrose960786e2018-04-21 12:10:00 +0200140 const char *k, *slot_name;
Jeff King75194432009-09-09 07:38:58 -0400141 int i;
142
Ryan Dammrose960786e2018-04-21 12:10:00 +0200143 if (!strcmp(var, "color.advice")) {
144 advice_use_color = git_config_colorbool(var, value);
145 return 0;
146 }
147
148 if (skip_prefix(var, "color.advice.", &slot_name)) {
149 int slot = parse_advise_color_slot(slot_name);
150 if (slot < 0)
151 return 0;
152 if (!value)
153 return config_error_nonbool(var);
154 return color_parse(value, advice_colors[slot]);
155 }
156
Jeff Kingcf4fff52014-06-18 15:44:19 -0400157 if (!skip_prefix(var, "advice.", &k))
158 return 0;
159
Heba Walyb3b18d12020-03-02 20:01:59 +0000160 for (i = 0; i < ARRAY_SIZE(advice_setting); i++) {
161 if (strcasecmp(k, advice_setting[i].key))
162 continue;
163 advice_setting[i].enabled = git_config_bool(var, value);
Jeff King75194432009-09-09 07:38:58 -0400164 return 0;
165 }
166
167 return 0;
168}
Matthieu Moyd38a30d2010-01-12 10:54:44 +0100169
Nguyễn Thái Ngọc Duy3ac68a92018-05-26 15:55:24 +0200170void list_config_advices(struct string_list *list, const char *prefix)
171{
172 int i;
173
Heba Walyb3b18d12020-03-02 20:01:59 +0000174 for (i = 0; i < ARRAY_SIZE(advice_setting); i++)
175 list_config_item(list, prefix, advice_setting[i].key);
Nguyễn Thái Ngọc Duy3ac68a92018-05-26 15:55:24 +0200176}
177
Ramkumar Ramachandra38ef61c2011-08-04 16:08:59 +0530178int error_resolve_conflict(const char *me)
Matthieu Moyd38a30d2010-01-12 10:54:44 +0100179{
Vasco Almeida8785c422016-06-17 20:20:52 +0000180 if (!strcmp(me, "cherry-pick"))
181 error(_("Cherry-picking is not possible because you have unmerged files."));
182 else if (!strcmp(me, "commit"))
183 error(_("Committing is not possible because you have unmerged files."));
184 else if (!strcmp(me, "merge"))
185 error(_("Merging is not possible because you have unmerged files."));
186 else if (!strcmp(me, "pull"))
187 error(_("Pulling is not possible because you have unmerged files."));
188 else if (!strcmp(me, "revert"))
189 error(_("Reverting is not possible because you have unmerged files."));
190 else
191 error(_("It is not possible to %s because you have unmerged files."),
192 me);
193
Ben Boeckeled9bff02021-08-23 12:44:00 +0200194 if (advice_enabled(ADVICE_RESOLVE_CONFLICT))
Matthieu Moyd38a30d2010-01-12 10:54:44 +0100195 /*
196 * Message used both when 'git commit' fails and when
197 * other commands doing a merge do.
198 */
Jeff Kingc057b242014-06-03 03:17:17 -0400199 advise(_("Fix them up in the work tree, and then use 'git add/rm <file>'\n"
Matthieu Moy91e70e02014-08-28 11:46:58 +0200200 "as appropriate to mark resolution and make a commit."));
Ramkumar Ramachandra38ef61c2011-08-04 16:08:59 +0530201 return -1;
202}
203
204void NORETURN die_resolve_conflict(const char *me)
205{
206 error_resolve_conflict(me);
Vasco Almeida8785c422016-06-17 20:20:52 +0000207 die(_("Exiting because of an unresolved conflict."));
Matthieu Moyd38a30d2010-01-12 10:54:44 +0100208}
Nguyễn Thái Ngọc Duy28570932012-01-16 16:46:16 +0700209
Paul Tan4a4cf9e2015-06-18 18:54:04 +0800210void NORETURN die_conclude_merge(void)
211{
212 error(_("You have not concluded your merge (MERGE_HEAD exists)."));
Ben Boeckeled9bff02021-08-23 12:44:00 +0200213 if (advice_enabled(ADVICE_RESOLVE_CONFLICT))
Alex Henrieb7447672015-10-01 22:25:33 -0600214 advise(_("Please, commit your changes before merging."));
Paul Tan4a4cf9e2015-06-18 18:54:04 +0800215 die(_("Exiting because of unfinished merge."));
216}
217
Alex Henrie3d5fc242021-07-21 01:42:19 +0000218void NORETURN die_ff_impossible(void)
219{
220 die(_("Not possible to fast-forward, aborting."));
221}
222
Matheus Tavaresa20f7042021-04-08 17:41:27 -0300223void advise_on_updating_sparse_paths(struct string_list *pathspec_list)
224{
225 struct string_list_item *item;
226
227 if (!pathspec_list->nr)
228 return;
229
Derrick Stolee6579e782021-09-24 15:39:14 +0000230 fprintf(stderr, _("The following paths and/or pathspecs matched paths that exist\n"
231 "outside of your sparse-checkout definition, so will not be\n"
232 "updated in the index:\n"));
Matheus Tavaresa20f7042021-04-08 17:41:27 -0300233 for_each_string_list_item(item, pathspec_list)
234 fprintf(stderr, "%s\n", item->string);
235
236 advise_if_enabled(ADVICE_UPDATE_SPARSE_PATH,
Derrick Stolee6579e782021-09-24 15:39:14 +0000237 _("If you intend to update such entries, try one of the following:\n"
238 "* Use the --sparse option.\n"
239 "* Disable or modify the sparsity rules."));
Matheus Tavaresa20f7042021-04-08 17:41:27 -0300240}
241
Nguyễn Thái Ngọc Duy28570932012-01-16 16:46:16 +0700242void detach_advice(const char *new_name)
243{
Vasco Almeidae9f3cec2016-06-17 20:20:51 +0000244 const char *fmt =
Nguyễn Thái Ngọc Duy328c6cb2019-03-29 17:39:19 +0700245 _("Note: switching to '%s'.\n"
Nguyễn Thái Ngọc Duyaf9ded52019-03-29 17:38:58 +0700246 "\n"
Nguyễn Thái Ngọc Duy28570932012-01-16 16:46:16 +0700247 "You are in 'detached HEAD' state. You can look around, make experimental\n"
248 "changes and commit them, and you can discard any commits you make in this\n"
Nguyễn Thái Ngọc Duy328c6cb2019-03-29 17:39:19 +0700249 "state without impacting any branches by switching back to a branch.\n"
Nguyễn Thái Ngọc Duyaf9ded52019-03-29 17:38:58 +0700250 "\n"
Nguyễn Thái Ngọc Duy28570932012-01-16 16:46:16 +0700251 "If you want to create a new branch to retain commits you create, you may\n"
Nguyễn Thái Ngọc Duy328c6cb2019-03-29 17:39:19 +0700252 "do so (now or later) by using -c with the switch command. Example:\n"
Nguyễn Thái Ngọc Duyaf9ded52019-03-29 17:38:58 +0700253 "\n"
Nguyễn Thái Ngọc Duy328c6cb2019-03-29 17:39:19 +0700254 " git switch -c <new-branch-name>\n"
Nguyễn Thái Ngọc Duyaf9ded52019-03-29 17:38:58 +0700255 "\n"
Nguyễn Thái Ngọc Duy328c6cb2019-03-29 17:39:19 +0700256 "Or undo this operation with:\n"
Nguyễn Thái Ngọc Duyaf9ded52019-03-29 17:38:58 +0700257 "\n"
Nguyễn Thái Ngọc Duy328c6cb2019-03-29 17:39:19 +0700258 " git switch -\n"
Nguyễn Thái Ngọc Duyaf9ded52019-03-29 17:38:58 +0700259 "\n"
260 "Turn off this advice by setting config variable advice.detachedHead to false\n\n");
Nguyễn Thái Ngọc Duy28570932012-01-16 16:46:16 +0700261
262 fprintf(stderr, fmt, new_name);
263}