diff --git a/builtin/config.c b/builtin/config.c
index 98d65bc0ad..9a9c2d12f2 100644
--- a/builtin/config.c
+++ b/builtin/config.c
@@ -29,10 +29,11 @@ static int use_worktree_config;
 static struct git_config_source given_config_source;
 static int actions, type;
 static char *default_value;
-static int end_null;
+static int end_nul;
 static int respect_includes_opt = -1;
 static struct config_options config_options;
 static int show_origin;
+static int show_scope;
 
 #define ACTION_GET (1<<0)
 #define ACTION_GET_ALL (1<<1)
@@ -151,10 +152,11 @@ static struct option builtin_config_options[] = {
 	OPT_CALLBACK_VALUE(0, "path", &type, N_("value is a path (file or directory name)"), TYPE_PATH),
 	OPT_CALLBACK_VALUE(0, "expiry-date", &type, N_("value is an expiry date"), TYPE_EXPIRY_DATE),
 	OPT_GROUP(N_("Other")),
-	OPT_BOOL('z', "null", &end_null, N_("terminate values with NUL byte")),
+	OPT_BOOL('z', "null", &end_nul, N_("terminate values with NUL byte")),
 	OPT_BOOL(0, "name-only", &omit_values, N_("show variable names only")),
 	OPT_BOOL(0, "includes", &respect_includes_opt, N_("respect include directives on lookup")),
 	OPT_BOOL(0, "show-origin", &show_origin, N_("show origin of config (file, standard input, blob, command line)")),
+	OPT_BOOL(0, "show-scope", &show_scope, N_("show scope of config (system, global, local, command line)")),
 	OPT_STRING(0, "default", &default_value, N_("value"), N_("with --get, use default value when missing entry")),
 	OPT_END(),
 };
@@ -178,23 +180,63 @@ static void check_argc(int argc, int min, int max)
 
 static void show_config_origin(struct strbuf *buf)
 {
-	const char term = end_null ? '\0' : '\t';
+	const char term = end_nul ? '\0' : '\t';
 
 	strbuf_addstr(buf, current_config_origin_type());
 	strbuf_addch(buf, ':');
-	if (end_null)
+	if (end_nul)
 		strbuf_addstr(buf, current_config_name());
 	else
 		quote_c_style(current_config_name(), buf, NULL, 0);
 	strbuf_addch(buf, term);
 }
 
+static const char *scope_to_string(enum config_scope scope) {
+	/*
+	 * --local, --global, and --system work the same as --file so there's
+	 * no easy way for the parser to tell the difference when it is
+	 * setting the scope, so we use our information about which options
+	 * were passed
+	 */
+	if (use_local_config || scope == CONFIG_SCOPE_REPO) {
+		return "local";
+	} else if (use_global_config || scope == CONFIG_SCOPE_GLOBAL) {
+		return "global";
+	} else if (use_system_config || scope == CONFIG_SCOPE_SYSTEM) {
+		return "system";
+	} else if (given_config_source.use_stdin ||
+		given_config_source.blob ||
+		given_config_source.file ||
+		scope == CONFIG_SCOPE_CMDLINE) {
+		return "command line";
+	} else {
+		return "unknown";
+	}
+}
+
+static void show_config_scope(struct strbuf *buf)
+{
+	const char term = end_nul ? '\0' : '\t';
+	const char *scope = scope_to_string(current_config_scope());
+
+	strbuf_addch(buf, '(');
+	if (end_nul)
+		strbuf_addstr(buf, N_(scope));
+	else
+		quote_c_style(scope, buf, NULL, 0);
+	strbuf_addch(buf, ')');
+	strbuf_addch(buf, term);
+}
+
 static int show_all_config(const char *key_, const char *value_, void *cb)
 {
-	if (show_origin) {
+	if (show_origin || show_scope) {
 		struct strbuf buf = STRBUF_INIT;
-		show_config_origin(&buf);
-		/* Use fwrite as "buf" can contain \0's if "end_null" is set. */
+		if (show_scope)
+			show_config_scope(&buf);
+		if (show_origin)
+			show_config_origin(&buf);
+		/* Use fwrite as "buf" can contain \0's if "end_nul" is set. */
 		fwrite(buf.buf, 1, buf.len, stdout);
 		strbuf_release(&buf);
 	}
@@ -213,6 +255,8 @@ struct strbuf_list {
 
 static int format_config(struct strbuf *buf, const char *key_, const char *value_)
 {
+	if (show_scope)
+		show_config_scope(buf);
 	if (show_origin)
 		show_config_origin(buf);
 	if (show_keys)
@@ -678,7 +722,7 @@ int cmd_config(int argc, const char **argv, const char *prefix)
 		config_options.git_dir = get_git_dir();
 	}
 
-	if (end_null) {
+	if (end_nul) {
 		term = '\0';
 		delim = '\n';
 		key_delim = '\n';
diff --git a/t/t1300-config.sh b/t/t1300-config.sh
index 983a0a1583..098f305bdd 100755
--- a/t/t1300-config.sh
+++ b/t/t1300-config.sh
@@ -1766,6 +1766,57 @@ test_expect_success !MINGW '--show-origin blob ref' '
 	test_cmp expect output
 '
 
+
+test_expect_success '--show-scope with --list' '
+	cat >expect <<-EOF &&
+		(global)	user.global=true
+		(global)	user.override=global
+		(global)	include.path=$INCLUDE_DIR/absolute.include
+		(global)	user.absolute=include
+		(local)	user.local=true
+		(local)	user.override=local
+		(local)	include.path=../include/relative.include
+		(local)	user.relative=include
+		(command line)	user.cmdline=true
+	EOF
+	git -c user.cmdline=true config --list --show-scope >output &&
+	test_cmp expect output
+'
+
+test_expect_success !MINGW '--show-scope with --blob' '
+	blob=$(git hash-object -w "$CUSTOM_CONFIG_FILE") &&
+	cat >expect <<-EOF &&
+		(command line)	user.custom=true
+	EOF
+	git config --blob=$blob --show-scope --list >output &&
+	test_cmp expect output
+'
+test_expect_success '--show-scope with --local' '
+	cat >expect <<-\EOF &&
+		(local)	user.local=true
+		(local)	user.override=local
+		(local)	include.path=../include/relative.include
+	EOF
+	git config --local --list --show-scope >output &&
+	test_cmp expect output
+'
+
+test_expect_success '--show-scope with --show-origin' '
+	cat >expect <<-EOF &&
+		(global)	file:$HOME/.gitconfig	user.global=true
+		(global)	file:$HOME/.gitconfig	user.override=global
+		(global)	file:$HOME/.gitconfig	include.path=$INCLUDE_DIR/absolute.include
+		(global)	file:$INCLUDE_DIR/absolute.include	user.absolute=include
+		(local)	file:.git/config	user.local=true
+		(local)	file:.git/config	user.override=local
+		(local)	file:.git/config	include.path=../include/relative.include
+		(local)	file:.git/../include/relative.include	user.relative=include
+		(command line)	command line:	user.cmdline=true
+	EOF
+	git -c user.cmdline=true config --list --show-origin --show-scope >output &&
+	test_cmp expect output
+'
+
 test_expect_success '--local requires a repo' '
 	# we expect 128 to ensure that we do not simply
 	# fail to find anything and return code "1"
