builtin/checkout.c: use "ret" variable for return
[git/git.git] / advice.c
CommitLineData
75194438 1#include "cache.h"
b2141fc1 2#include "config.h"
960786e7 3#include "color.h"
75194438 4
1184564e 5int advice_push_update_rejected = 1;
f25950f3 6int advice_push_non_ff_current = 1;
f25950f3 7int advice_push_non_ff_matching = 1;
b4505682 8int advice_push_already_exists = 1;
75e5c0dc
JH
9int advice_push_fetch_first = 1;
10int advice_push_needs_force = 1;
edf563fb 11int advice_status_hints = 1;
6a38ef2c 12int advice_status_u_option = 1;
4c371f91 13int advice_commit_before_merge = 1;
d38a30df 14int advice_resolve_conflict = 1;
b706fcfe 15int advice_implicit_identity = 1;
13be3e31 16int advice_detached_head = 1;
caa2036b 17int advice_set_upstream_failure = 1;
798c35fc 18int advice_object_name_warning = 1;
7e309446 19int advice_rm_hints = 1;
53213994 20int advice_add_embedded_repo = 1;
f805a00a 21int advice_ignored_hook = 1;
abfb04d0 22int advice_waiting_for_editor = 1;
f9f99b3f 23int advice_graft_file_deprecated = 1;
75194438 24
960786e7
RD
25static int advice_use_color = -1;
26static char advice_colors[][COLOR_MAXLEN] = {
27 GIT_COLOR_RESET,
28 GIT_COLOR_YELLOW, /* HINT */
29};
30
31enum color_advice {
32 ADVICE_COLOR_RESET = 0,
33 ADVICE_COLOR_HINT = 1,
34};
35
36static int parse_advise_color_slot(const char *slot)
37{
38 if (!strcasecmp(slot, "reset"))
39 return ADVICE_COLOR_RESET;
40 if (!strcasecmp(slot, "hint"))
41 return ADVICE_COLOR_HINT;
42 return -1;
43}
44
45static const char *advise_get_color(enum color_advice ix)
46{
47 if (want_color_stderr(advice_use_color))
48 return advice_colors[ix];
49 return "";
50}
51
75194438
JK
52static struct {
53 const char *name;
54 int *preference;
55} advice_config[] = {
1184564e 56 { "pushupdaterejected", &advice_push_update_rejected },
f25950f3 57 { "pushnonffcurrent", &advice_push_non_ff_current },
f25950f3 58 { "pushnonffmatching", &advice_push_non_ff_matching },
b4505682 59 { "pushalreadyexists", &advice_push_already_exists },
75e5c0dc
JH
60 { "pushfetchfirst", &advice_push_fetch_first },
61 { "pushneedsforce", &advice_push_needs_force },
edf563fb 62 { "statushints", &advice_status_hints },
6a38ef2c 63 { "statusuoption", &advice_status_u_option },
4c371f91 64 { "commitbeforemerge", &advice_commit_before_merge },
d38a30df 65 { "resolveconflict", &advice_resolve_conflict },
b706fcfe 66 { "implicitidentity", &advice_implicit_identity },
13be3e31 67 { "detachedhead", &advice_detached_head },
caa2036b 68 { "setupstreamfailure", &advice_set_upstream_failure },
8dc84fdc 69 { "objectnamewarning", &advice_object_name_warning },
7e309446 70 { "rmhints", &advice_rm_hints },
53213994 71 { "addembeddedrepo", &advice_add_embedded_repo },
f805a00a 72 { "ignoredhook", &advice_ignored_hook },
abfb04d0 73 { "waitingforeditor", &advice_waiting_for_editor },
f9f99b3f 74 { "graftfiledeprecated", &advice_graft_file_deprecated },
1184564e
CR
75
76 /* make this an alias for backward compatibility */
77 { "pushnonfastforward", &advice_push_update_rejected }
75194438
JK
78};
79
38ef61cf
RR
80void advise(const char *advice, ...)
81{
23cb5bf3 82 struct strbuf buf = STRBUF_INIT;
38ef61cf 83 va_list params;
23cb5bf3 84 const char *cp, *np;
38ef61cf
RR
85
86 va_start(params, advice);
447b99c8 87 strbuf_vaddf(&buf, advice, params);
38ef61cf 88 va_end(params);
23cb5bf3
JH
89
90 for (cp = buf.buf; *cp; cp = np) {
91 np = strchrnul(cp, '\n');
960786e7
RD
92 fprintf(stderr, _("%shint: %.*s%s\n"),
93 advise_get_color(ADVICE_COLOR_HINT),
94 (int)(np - cp), cp,
95 advise_get_color(ADVICE_COLOR_RESET));
23cb5bf3
JH
96 if (*np)
97 np++;
98 }
99 strbuf_release(&buf);
38ef61cf
RR
100}
101
75194438
JK
102int git_default_advice_config(const char *var, const char *value)
103{
960786e7 104 const char *k, *slot_name;
75194438
JK
105 int i;
106
960786e7
RD
107 if (!strcmp(var, "color.advice")) {
108 advice_use_color = git_config_colorbool(var, value);
109 return 0;
110 }
111
112 if (skip_prefix(var, "color.advice.", &slot_name)) {
113 int slot = parse_advise_color_slot(slot_name);
114 if (slot < 0)
115 return 0;
116 if (!value)
117 return config_error_nonbool(var);
118 return color_parse(value, advice_colors[slot]);
119 }
120
cf4fff57
JK
121 if (!skip_prefix(var, "advice.", &k))
122 return 0;
123
75194438
JK
124 for (i = 0; i < ARRAY_SIZE(advice_config); i++) {
125 if (strcmp(k, advice_config[i].name))
126 continue;
127 *advice_config[i].preference = git_config_bool(var, value);
128 return 0;
129 }
130
131 return 0;
132}
d38a30df 133
38ef61cf 134int error_resolve_conflict(const char *me)
d38a30df 135{
8785c425
VA
136 if (!strcmp(me, "cherry-pick"))
137 error(_("Cherry-picking is not possible because you have unmerged files."));
138 else if (!strcmp(me, "commit"))
139 error(_("Committing is not possible because you have unmerged files."));
140 else if (!strcmp(me, "merge"))
141 error(_("Merging is not possible because you have unmerged files."));
142 else if (!strcmp(me, "pull"))
143 error(_("Pulling is not possible because you have unmerged files."));
144 else if (!strcmp(me, "revert"))
145 error(_("Reverting is not possible because you have unmerged files."));
146 else
147 error(_("It is not possible to %s because you have unmerged files."),
148 me);
149
23cb5bf3 150 if (advice_resolve_conflict)
d38a30df
MM
151 /*
152 * Message used both when 'git commit' fails and when
153 * other commands doing a merge do.
154 */
c057b242 155 advise(_("Fix them up in the work tree, and then use 'git add/rm <file>'\n"
91e70e00 156 "as appropriate to mark resolution and make a commit."));
38ef61cf
RR
157 return -1;
158}
159
160void NORETURN die_resolve_conflict(const char *me)
161{
162 error_resolve_conflict(me);
8785c425 163 die(_("Exiting because of an unresolved conflict."));
d38a30df 164}
2857093b 165
4a4cf9e8
PT
166void NORETURN die_conclude_merge(void)
167{
168 error(_("You have not concluded your merge (MERGE_HEAD exists)."));
169 if (advice_resolve_conflict)
b7447679 170 advise(_("Please, commit your changes before merging."));
4a4cf9e8
PT
171 die(_("Exiting because of unfinished merge."));
172}
173
2857093b
NTND
174void detach_advice(const char *new_name)
175{
e9f3cec4
VA
176 const char *fmt =
177 _("Note: checking out '%s'.\n\n"
2857093b
NTND
178 "You are in 'detached HEAD' state. You can look around, make experimental\n"
179 "changes and commit them, and you can discard any commits you make in this\n"
180 "state without impacting any branches by performing another checkout.\n\n"
181 "If you want to create a new branch to retain commits you create, you may\n"
182 "do so (now or later) by using -b with the checkout command again. Example:\n\n"
e9f3cec4 183 " git checkout -b <new-branch-name>\n\n");
2857093b
NTND
184
185 fprintf(stderr, fmt, new_name);
186}