Merge branch 'js/untracked-cache-allocfix'
[gitweb.git] / advice.c
index 406efc183ba272b94a39d4cc7e97d7483a40a9d4..567209aa79afee0443dd0d7049343e1a004ae784 100644 (file)
--- a/advice.c
+++ b/advice.c
@@ -1,5 +1,7 @@
 #include "cache.h"
 #include "config.h"
+#include "color.h"
+#include "help.h"
 
 int advice_push_update_rejected = 1;
 int advice_push_non_ff_current = 1;
@@ -7,44 +9,81 @@ int advice_push_non_ff_matching = 1;
 int advice_push_already_exists = 1;
 int advice_push_fetch_first = 1;
 int advice_push_needs_force = 1;
+int advice_push_unqualified_ref_name = 1;
 int advice_status_hints = 1;
 int advice_status_u_option = 1;
 int advice_commit_before_merge = 1;
+int advice_reset_quiet_warning = 1;
 int advice_resolve_conflict = 1;
 int advice_implicit_identity = 1;
 int advice_detached_head = 1;
 int advice_set_upstream_failure = 1;
 int advice_object_name_warning = 1;
+int advice_amworkdir = 1;
 int advice_rm_hints = 1;
 int advice_add_embedded_repo = 1;
 int advice_ignored_hook = 1;
 int advice_waiting_for_editor = 1;
+int advice_graft_file_deprecated = 1;
+int advice_checkout_ambiguous_remote_branch_name = 1;
+
+static int advice_use_color = -1;
+static char advice_colors[][COLOR_MAXLEN] = {
+       GIT_COLOR_RESET,
+       GIT_COLOR_YELLOW,       /* HINT */
+};
+
+enum color_advice {
+       ADVICE_COLOR_RESET = 0,
+       ADVICE_COLOR_HINT = 1,
+};
+
+static int parse_advise_color_slot(const char *slot)
+{
+       if (!strcasecmp(slot, "reset"))
+               return ADVICE_COLOR_RESET;
+       if (!strcasecmp(slot, "hint"))
+               return ADVICE_COLOR_HINT;
+       return -1;
+}
+
+static const char *advise_get_color(enum color_advice ix)
+{
+       if (want_color_stderr(advice_use_color))
+               return advice_colors[ix];
+       return "";
+}
 
 static struct {
        const char *name;
        int *preference;
 } advice_config[] = {
-       { "pushupdaterejected", &advice_push_update_rejected },
-       { "pushnonffcurrent", &advice_push_non_ff_current },
-       { "pushnonffmatching", &advice_push_non_ff_matching },
-       { "pushalreadyexists", &advice_push_already_exists },
-       { "pushfetchfirst", &advice_push_fetch_first },
-       { "pushneedsforce", &advice_push_needs_force },
-       { "statushints", &advice_status_hints },
-       { "statusuoption", &advice_status_u_option },
-       { "commitbeforemerge", &advice_commit_before_merge },
-       { "resolveconflict", &advice_resolve_conflict },
-       { "implicitidentity", &advice_implicit_identity },
-       { "detachedhead", &advice_detached_head },
-       { "setupstreamfailure", &advice_set_upstream_failure },
-       { "objectnamewarning", &advice_object_name_warning },
-       { "rmhints", &advice_rm_hints },
-       { "addembeddedrepo", &advice_add_embedded_repo },
-       { "ignoredhook", &advice_ignored_hook },
-       { "waitingforeditor", &advice_waiting_for_editor },
+       { "pushUpdateRejected", &advice_push_update_rejected },
+       { "pushNonFFCurrent", &advice_push_non_ff_current },
+       { "pushNonFFMatching", &advice_push_non_ff_matching },
+       { "pushAlreadyExists", &advice_push_already_exists },
+       { "pushFetchFirst", &advice_push_fetch_first },
+       { "pushNeedsForce", &advice_push_needs_force },
+       { "pushUnqualifiedRefName", &advice_push_unqualified_ref_name },
+       { "statusHints", &advice_status_hints },
+       { "statusUoption", &advice_status_u_option },
+       { "commitBeforeMerge", &advice_commit_before_merge },
+       { "resetQuiet", &advice_reset_quiet_warning },
+       { "resolveConflict", &advice_resolve_conflict },
+       { "implicitIdentity", &advice_implicit_identity },
+       { "detachedHead", &advice_detached_head },
+       { "setupStreamFailure", &advice_set_upstream_failure },
+       { "objectNameWarning", &advice_object_name_warning },
+       { "amWorkDir", &advice_amworkdir },
+       { "rmHints", &advice_rm_hints },
+       { "addEmbeddedRepo", &advice_add_embedded_repo },
+       { "ignoredHook", &advice_ignored_hook },
+       { "waitingForEditor", &advice_waiting_for_editor },
+       { "graftFileDeprecated", &advice_graft_file_deprecated },
+       { "checkoutAmbiguousRemoteBranchName", &advice_checkout_ambiguous_remote_branch_name },
 
        /* make this an alias for backward compatibility */
-       { "pushnonfastforward", &advice_push_update_rejected }
+       { "pushNonFastForward", &advice_push_update_rejected }
 };
 
 void advise(const char *advice, ...)
@@ -59,7 +98,10 @@ void advise(const char *advice, ...)
 
        for (cp = buf.buf; *cp; cp = np) {
                np = strchrnul(cp, '\n');
-               fprintf(stderr, _("hint: %.*s\n"), (int)(np - cp), cp);
+               fprintf(stderr, _("%shint: %.*s%s\n"),
+                       advise_get_color(ADVICE_COLOR_HINT),
+                       (int)(np - cp), cp,
+                       advise_get_color(ADVICE_COLOR_RESET));
                if (*np)
                        np++;
        }
@@ -68,14 +110,28 @@ void advise(const char *advice, ...)
 
 int git_default_advice_config(const char *var, const char *value)
 {
-       const char *k;
+       const char *k, *slot_name;
        int i;
 
+       if (!strcmp(var, "color.advice")) {
+               advice_use_color = git_config_colorbool(var, value);
+               return 0;
+       }
+
+       if (skip_prefix(var, "color.advice.", &slot_name)) {
+               int slot = parse_advise_color_slot(slot_name);
+               if (slot < 0)
+                       return 0;
+               if (!value)
+                       return config_error_nonbool(var);
+               return color_parse(value, advice_colors[slot]);
+       }
+
        if (!skip_prefix(var, "advice.", &k))
                return 0;
 
        for (i = 0; i < ARRAY_SIZE(advice_config); i++) {
-               if (strcmp(k, advice_config[i].name))
+               if (strcasecmp(k, advice_config[i].name))
                        continue;
                *advice_config[i].preference = git_config_bool(var, value);
                return 0;
@@ -84,6 +140,14 @@ int git_default_advice_config(const char *var, const char *value)
        return 0;
 }
 
+void list_config_advices(struct string_list *list, const char *prefix)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(advice_config); i++)
+               list_config_item(list, prefix, advice_config[i].name);
+}
+
 int error_resolve_conflict(const char *me)
 {
        if (!strcmp(me, "cherry-pick"))