diff --git a/Documentation/config/remote.txt b/Documentation/config/remote.txt
index 024f92befc..4118c219c1 100644
--- a/Documentation/config/remote.txt
+++ b/Documentation/config/remote.txt
@@ -106,10 +106,12 @@ remote.<name>.followRemoteHEAD::
 	How linkgit:git-fetch[1] should handle updates to `remotes/<name>/HEAD`.
 	The default value is "create", which will create `remotes/<name>/HEAD`
 	if it exists on the remote, but not locally, but will not touch an
-	already existing local reference.  Setting to "warn" will print
+	already existing local reference. Setting to "warn" will print
 	a message if the remote has a different value, than the local one and
-	in case there is no local reference, it behaves like "create". Setting
-	to "always" will silently update it to the value on the remote.
+	in case there is no local reference, it behaves like "create".
+	A variant on "warn" is "warn-if-not-$branch", which behaves like
+	"warn", but if `HEAD` on the remote is `$branch` it will be silent.
+	Setting to "always" will silently update it to the value on the remote.
 	Finally, setting it to "never" will never change or create the local
 	reference.
 +
diff --git a/builtin/fetch.c b/builtin/fetch.c
index 087beb4c92..b3f6793026 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -1584,10 +1584,12 @@ static void set_head_advice_msg(const char *remote, const char *head_name)
 	const char message_advice_set_head[] =
 	N_("Run 'git remote set-head %s %s' to follow the change, or set\n"
 	   "'remote.%s.followRemoteHEAD' configuration option to a different value\n"
-	   "if you do not want to see this message.");
+	   "if you do not want to see this message. Specifically running\n"
+	   "'git config set remote.%s.followRemoteHEAD %s' will disable the warning\n"
+	   "until the remote changes HEAD to something else.");
 
 	advise_if_enabled(ADVICE_FETCH_SET_HEAD_WARN, _(message_advice_set_head),
-			remote, head_name, remote);
+			remote, head_name, remote, remote, head_name);
 }
 
 static void report_set_head(const char *remote, const char *head_name,
@@ -1612,7 +1614,8 @@ static void report_set_head(const char *remote, const char *head_name,
 	strbuf_release(&buf_prefix);
 }
 
-static int set_head(const struct ref *remote_refs, int follow_remote_head)
+static int set_head(const struct ref *remote_refs, int follow_remote_head,
+		const char *no_warn_branch)
 {
 	int result = 0, create_only, is_bare, was_detached;
 	struct strbuf b_head = STRBUF_INIT, b_remote_head = STRBUF_INIT,
@@ -1669,7 +1672,9 @@ static int set_head(const struct ref *remote_refs, int follow_remote_head)
 		result = 1;
 		goto cleanup;
 	}
-	if (follow_remote_head == FOLLOW_REMOTE_WARN && verbosity >= 0)
+	if (verbosity >= 0 &&
+		follow_remote_head == FOLLOW_REMOTE_WARN &&
+		(!no_warn_branch || strcmp(no_warn_branch, head_name)))
 		report_set_head(remote, head_name, &b_local_head, was_detached);
 
 cleanup:
@@ -1898,7 +1903,8 @@ static int do_fetch(struct transport *transport,
 				  "you need to specify exactly one branch with the --set-upstream option"));
 		}
 	}
-	if (set_head(remote_refs, transport->remote->follow_remote_head))
+	if (set_head(remote_refs, transport->remote->follow_remote_head,
+		transport->remote->no_warn_branch))
 		;
 		/*
 		 * Way too many cases where this can go wrong
diff --git a/remote.c b/remote.c
index 0b18840d43..4ec5d3f47b 100644
--- a/remote.c
+++ b/remote.c
@@ -515,14 +515,23 @@ static int handle_config(const char *key, const char *value,
 		return parse_transport_option(key, value,
 					      &remote->server_options);
 	} else if (!strcmp(subkey, "followremotehead")) {
+		const char *no_warn_branch;
 		if (!strcmp(value, "never"))
 			remote->follow_remote_head = FOLLOW_REMOTE_NEVER;
 		else if (!strcmp(value, "create"))
 			remote->follow_remote_head = FOLLOW_REMOTE_CREATE;
-		else if (!strcmp(value, "warn"))
+		else if (!strcmp(value, "warn")) {
 			remote->follow_remote_head = FOLLOW_REMOTE_WARN;
-		else if (!strcmp(value, "always"))
+			remote->no_warn_branch = NULL;
+		} else if (skip_prefix(value, "warn-if-not-", &no_warn_branch)) {
+			remote->follow_remote_head = FOLLOW_REMOTE_WARN;
+			remote->no_warn_branch = no_warn_branch;
+		} else if (!strcmp(value, "always")) {
 			remote->follow_remote_head = FOLLOW_REMOTE_ALWAYS;
+		} else {
+			warning(_("unrecognized followRemoteHEAD value '%s' ignored"),
+				value);
+		}
 	}
 	return 0;
 }
diff --git a/remote.h b/remote.h
index 184b35653d..bda10dd5c8 100644
--- a/remote.h
+++ b/remote.h
@@ -116,6 +116,7 @@ struct remote {
 	struct string_list server_options;
 
 	enum follow_remote_head_settings follow_remote_head;
+	const char *no_warn_branch;
 };
 
 /**
diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh
index 5d7ee1b550..5c9915b836 100755
--- a/t/t5510-fetch.sh
+++ b/t/t5510-fetch.sh
@@ -181,6 +181,44 @@ test_expect_success "fetch test followRemoteHEAD warn quiet" '
 	)
 '
 
+test_expect_success "fetch test followRemoteHEAD warn-if-not-branch branch is same" '
+	test_when_finished "git config unset remote.origin.followRemoteHEAD" &&
+	(
+		cd "$D" &&
+		cd two &&
+		git rev-parse --verify refs/remotes/origin/other &&
+		git remote set-head origin other &&
+		git rev-parse --verify refs/remotes/origin/HEAD &&
+		git rev-parse --verify refs/remotes/origin/main &&
+		git config set remote.origin.followRemoteHEAD "warn-if-not-main" &&
+		output=$(git fetch) &&
+		test "z" = "z$output" &&
+		head=$(git rev-parse refs/remotes/origin/HEAD) &&
+		branch=$(git rev-parse refs/remotes/origin/other) &&
+		test "z$head" = "z$branch"
+	)
+'
+
+test_expect_success "fetch test followRemoteHEAD warn-if-not-branch branch is different" '
+	test_when_finished "git config unset remote.origin.followRemoteHEAD" &&
+	(
+		cd "$D" &&
+		cd two &&
+		git rev-parse --verify refs/remotes/origin/other &&
+		git remote set-head origin other &&
+		git rev-parse --verify refs/remotes/origin/HEAD &&
+		git rev-parse --verify refs/remotes/origin/main &&
+		git config set remote.origin.followRemoteHEAD "warn-if-not-some/different-branch" &&
+		git fetch >output &&
+		echo "${SQ}HEAD${SQ} at ${SQ}origin${SQ} is ${SQ}main${SQ}," \
+			"but we have ${SQ}other${SQ} locally." >expect &&
+		test_cmp expect output &&
+		head=$(git rev-parse refs/remotes/origin/HEAD) &&
+		branch=$(git rev-parse refs/remotes/origin/other) &&
+		test "z$head" = "z$branch"
+	)
+'
+
 test_expect_success "fetch test followRemoteHEAD always" '
 	test_when_finished "git config unset remote.origin.followRemoteHEAD" &&
 	(
