Fix git_config_bool_or_int

The earlier one botched the return value logic between config_bool and
config_bool_and_int.  The former should normalize between 0 and 1 while
the latter should give back full range of integer values.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
diff --git a/builtin-config.c b/builtin-config.c
index c34bc8b..10447a7 100644
--- a/builtin-config.c
+++ b/builtin-config.c
@@ -3,7 +3,7 @@
 #include "color.h"
 
 static const char git_config_set_usage[] =
-"git-config [ --global | --system | [ -f | --file ] config-file ] [ --bool | --int ] [ -z | --null ] [--get | --get-all | --get-regexp | --replace-all | --add | --unset | --unset-all] name [value [value_regex]] | --rename-section old_name new_name | --remove-section name | --list | --get-color var [default] | --get-colorbool name [stdout-is-tty]";
+"git-config [ --global | --system | [ -f | --file ] config-file ] [ --bool | --int | --bool-or-int ] [ -z | --null ] [--get | --get-all | --get-regexp | --replace-all | --add | --unset | --unset-all] name [value [value_regex]] | --rename-section old_name new_name | --remove-section name | --list | --get-color var [default] | --get-colorbool name [stdout-is-tty]";
 
 static char *key;
 static regex_t *key_regexp;
@@ -16,7 +16,7 @@
 static char delim = '=';
 static char key_delim = ' ';
 static char term = '\n';
-static enum { T_RAW, T_INT, T_BOOL } type = T_RAW;
+static enum { T_RAW, T_INT, T_BOOL, T_BOOL_OR_INT } type = T_RAW;
 
 static int show_all_config(const char *key_, const char *value_)
 {
@@ -53,6 +53,14 @@
 		sprintf(value, "%d", git_config_int(key_, value_?value_:""));
 	else if (type == T_BOOL)
 		vptr = git_config_bool(key_, value_) ? "true" : "false";
+	else if (type == T_BOOL_OR_INT) {
+		int is_bool, v;
+		v = git_config_bool_or_int(key_, value_, &is_bool);
+		if (is_bool)
+			vptr = v ? "true" : "false";
+		else
+			sprintf(value, "%d", v);
+	}
 	else
 		vptr = value_?value_:"";
 	seen++;
@@ -157,6 +165,14 @@
 		else if (type == T_BOOL)
 			sprintf(normalized, "%s",
 				git_config_bool(key, value) ? "true" : "false");
+		else if (type == T_BOOL_OR_INT) {
+			int is_bool, v;
+			v = git_config_bool_or_int(key, value, &is_bool);
+			if (!is_bool)
+				sprintf(normalized, "%d", v);
+			else
+				sprintf(normalized, "%s", v ? "true" : "false");
+		}
 	}
 
 	return normalized;
@@ -273,6 +289,8 @@
 			type = T_INT;
 		else if (!strcmp(argv[1], "--bool"))
 			type = T_BOOL;
+		else if (!strcmp(argv[1], "--bool-or-int"))
+			type = T_BOOL_OR_INT;
 		else if (!strcmp(argv[1], "--list") || !strcmp(argv[1], "-l")) {
 			if (argc != 2)
 				usage(git_config_set_usage);
diff --git a/config.c b/config.c
index 5ea18ef..b0ada51 100644
--- a/config.c
+++ b/config.c
@@ -315,13 +315,13 @@
 	if (!strcasecmp(value, "false") || !strcasecmp(value, "no"))
 		return 0;
 	*is_bool = 0;
-	return git_config_int(name, value) != 0;
+	return git_config_int(name, value);
 }
 
 int git_config_bool(const char *name, const char *value)
 {
 	int discard;
-	return git_config_bool_or_int(name, value, &discard);
+	return !!git_config_bool_or_int(name, value, &discard);
 }
 
 int git_config_string(const char **dest, const char *var, const char *value)
diff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh
index b36a901..a675cbb 100755
--- a/t/t1300-repo-config.sh
+++ b/t/t1300-repo-config.sh
@@ -595,6 +595,64 @@
 
 rm .git/config
 
+cat >expect <<\EOF
+[bool]
+	true1 = true
+	true2 = true
+	false1 = false
+	false2 = false
+[int]
+	int1 = 0
+	int2 = 1
+	int3 = -1
+EOF
+
+test_expect_success 'get --bool-or-int' '
+	(
+		echo "[bool]"
+		echo true1
+		echo true2 = true
+		echo false = false
+		echo "[int]"
+		echo int1 = 0
+		echo int2 = 1
+		echo int3 = -1
+	) >>.git/config &&
+	test $(git config --bool-or-int bool.true1) = true &&
+	test $(git config --bool-or-int bool.true2) = true &&
+	test $(git config --bool-or-int bool.false) = false &&
+	test $(git config --bool-or-int int.int1) = 0 &&
+	test $(git config --bool-or-int int.int2) = 1 &&
+	test $(git config --bool-or-int int.int3) = -1
+
+'
+
+rm .git/config
+cat >expect <<\EOF
+[bool]
+	true1 = true
+	false1 = false
+	true2 = true
+	false2 = false
+[int]
+	int1 = 0
+	int2 = 1
+	int3 = -1
+EOF
+
+test_expect_success 'set --bool-or-int' '
+	git config --bool-or-int bool.true1 true &&
+	git config --bool-or-int bool.false1 false &&
+	git config --bool-or-int bool.true2 yes &&
+	git config --bool-or-int bool.false2 no &&
+	git config --bool-or-int int.int1 0 &&
+	git config --bool-or-int int.int2 1 &&
+	git config --bool-or-int int.int3 -1 &&
+	test_cmp expect .git/config
+'
+
+rm .git/config
+
 git config quote.leading " test"
 git config quote.ending "test "
 git config quote.semicolon "test;test"