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