config: fix sign comparison warnings

There are a couple of -Wsign-compare warnings in "config.c": - `prepare_include_condition_pattern()` is returns a signed integer, where it either returns a negative error code or the index of the last dir separator in a path. That index will always be a non-negative number, but we cannot just change the return type to a `size_t` due to it being re-used as error code. This is fixed by splitting up concerns: the return value is only used as error code, and the prefix is now returned via an out-pointer. This fixes a sign comparison warning when comparing `text.len < prefix`, - We treat `struct config_store_data::seen` as signed integer in several places even though it's unsigned. - There are multiple trivial sign comparison warnings where we use a signed loop index to iterate through an unsigned number of items. Fix all of these issues and drop the `DISABLE_SIGN_COMPARE_WARNINGS` macro. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed Jul 23, 2025 at 16:08 UTC b06408b817c70204542924db0c689f258f010f7e
1 file changed +21 -19
config.c
+21 -19
@@ -6,8 +6,6 @@
6 *
7 */
8
9 -#define DISABLE_SIGN_COMPARE_WARNINGS
10 -
9 #include "git-compat-util.h"
10 #include "abspath.h"
11 #include "date.h"
@@ -198,11 +196,12 @@ static void add_trailing_starstar_for_dir(struct strbuf *pat)
196 }
197
198 static int prepare_include_condition_pattern(const struct key_value_info *kvi,
201 - struct strbuf *pat)
199 + struct strbuf *pat,
200 + size_t *out)
201 {
202 struct strbuf path = STRBUF_INIT;
203 char *expanded;
205 - int prefix = 0;
204 + size_t prefix = 0;
205
206 expanded = interpolate_path(pat->buf, 1);
207 if (expanded) {
@@ -229,8 +228,10 @@ static int prepare_include_condition_pattern(const struct key_value_info *kvi,
228
229 add_trailing_starstar_for_dir(pat);
230
231 + *out = prefix;
232 +
233 strbuf_release(&path);
233 - return prefix;
234 + return 0;
235 }
236
237 static int include_by_gitdir(const struct key_value_info *kvi,
@@ -239,7 +240,8 @@ static int include_by_gitdir(const struct key_value_info *kvi,
240 {
241 struct strbuf text = STRBUF_INIT;
242 struct strbuf pattern = STRBUF_INIT;
242 - int ret = 0, prefix;
243 + size_t prefix;
244 + int ret = 0;
245 const char *git_dir;
246 int already_tried_absolute = 0;
247
@@ -250,12 +252,11 @@ static int include_by_gitdir(const struct key_value_info *kvi,
252
253 strbuf_realpath(&text, git_dir, 1);
254 strbuf_add(&pattern, cond, cond_len);
253 - prefix = prepare_include_condition_pattern(kvi, &pattern);
254 -
255 -again:
256 - if (prefix < 0)
255 + ret = prepare_include_condition_pattern(kvi, &pattern, &prefix);
256 + if (ret < 0)
257 goto done;
258
259 +again:
260 if (prefix > 0) {
261 /*
262 * perform literal matching on the prefix part so that
@@ -724,7 +725,6 @@ int git_config_from_parameters(config_fn_t fn, void *data)
725 if (env) {
726 unsigned long count;
727 char *endp;
727 - int i;
728
729 count = strtoul(env, &endp, 10);
730 if (*endp) {
@@ -736,10 +736,10 @@ int git_config_from_parameters(config_fn_t fn, void *data)
736 goto out;
737 }
738
739 - for (i = 0; i < count; i++) {
739 + for (unsigned long i = 0; i < count; i++) {
740 const char *key, *value;
741
742 - strbuf_addf(&envvar, "GIT_CONFIG_KEY_%d", i);
742 + strbuf_addf(&envvar, "GIT_CONFIG_KEY_%lu", i);
743 key = getenv_safe(&to_free, envvar.buf);
744 if (!key) {
745 ret = error(_("missing config key %s"), envvar.buf);
@@ -747,7 +747,7 @@ int git_config_from_parameters(config_fn_t fn, void *data)
747 }
748 strbuf_reset(&envvar);
749
750 - strbuf_addf(&envvar, "GIT_CONFIG_VALUE_%d", i);
750 + strbuf_addf(&envvar, "GIT_CONFIG_VALUE_%lu", i);
751 value = getenv_safe(&to_free, envvar.buf);
752 if (!value) {
753 ret = error(_("missing config value %s"), envvar.buf);
@@ -1614,13 +1614,13 @@ int config_with_options(config_fn_t fn, void *data,
1614
1615 static void configset_iter(struct config_set *set, config_fn_t fn, void *data)
1616 {
1617 - int i, value_index;
1617 + int value_index;
1618 struct string_list *values;
1619 struct config_set_element *entry;
1620 struct configset_list *list = &set->list;
1621 struct config_context ctx = CONFIG_CONTEXT_INIT;
1622
1623 - for (i = 0; i < list->nr; i++) {
1623 + for (size_t i = 0; i < list->nr; i++) {
1624 entry = list->items[i].e;
1625 value_index = list->items[i].value_index;
1626 values = &entry->value_list;
@@ -2470,10 +2470,11 @@ static ssize_t write_pair(int fd, const char *key, const char *value,
2470 */
2471 static void maybe_remove_section(struct config_store_data *store,
2472 size_t *begin_offset, size_t *end_offset,
2473 - int *seen_ptr)
2473 + unsigned *seen_ptr)
2474 {
2475 size_t begin;
2476 - int i, seen, section_seen = 0;
2476 + int section_seen = 0;
2477 + unsigned int i, seen;
2478
2479 /*
2480 * First, ensure that this is the first key, and that there are no
@@ -2716,7 +2717,8 @@ int repo_config_set_multivar_in_file_gently(struct repository *r,
2717 } else {
2718 struct stat st;
2719 size_t copy_begin, copy_end;
2719 - int i, new_line = 0;
2720 + unsigned i;
2721 + int new_line = 0;
2722 struct config_options opts;
2723
2724 if (!value_pattern)