fetch: refactor do_fetch handling of followRemoteHEAD

Update enum follow_remote_head_settings to include the value FOLLOW_REMOTE_UNCONFIGURED as the new zero-initialized value for followRemoteHEAD. This will allow us to distinguish between the variable being unset vs. explicitly set to 'create', which is ultimately the system default. The unnecessary indentation is removed. The do_fetch function is likewise updated to perform its own decision making to determine the effective followRemoteHEAD mode, falling back to the system default if necessary. This will enable the next patch to introduce a user-configurable default. Function set_head now accepts the mode as an argument rather than only considering the value defined by the remote. The use of the 'warn-if-not-$branch' value is awkward in the context of a global default, since the branches will differ between individual remotes. For this reason, it's left out of this scheme and handling of the no_warn_branch variable is untouched. Since a remote-specific value for followRemoteHEAD takes priority, we can assume that if remote->no_warn_branch is set, then the remote is also asserting FOLLOW_REMOTE_WARN as the effective operating mode, and it will be honored by do_fetch. Signed-off-by: Matt Hunter <m@lfurio.us> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Matt Hunter committed Jun 19, 2026 at 05:44 UTC 85ef88dc5511750218588dcc56b76b1b4ab67e7d
2 files changed +18 -10
builtin/fetch.c
+10 -4
@@ -1730,12 +1730,12 @@ static void warn_set_head(const char *remote, const char *head_name,
1730 strbuf_release(&buf_prefix);
1731 }
1732
1733 -static int set_head(const struct ref *remote_refs, struct remote *remote)
1733 +static int set_head(const struct ref *remote_refs, struct remote *remote,
1734 + int follow_remote_head)
1735 {
1736 int result = 0, create_only, baremirror, was_detached;
1737 struct strbuf b_head = STRBUF_INIT, b_remote_head = STRBUF_INIT,
1738 b_local_head = STRBUF_INIT;
1738 - int follow_remote_head = remote->follow_remote_head;
1739 const char *no_warn_branch = remote->no_warn_branch;
1740 char *head_name = NULL;
1741 struct ref *ref, *matches;
@@ -1902,6 +1902,7 @@ static int do_fetch(struct transport *transport,
1902 struct ref_update_display_info_array display_array = { 0 };
1903 struct strmap rejected_refs = STRMAP_INIT;
1904 int summary_width = 0;
1905 + int follow_remote_head;
1906
1907 if (tags == TAGS_DEFAULT) {
1908 if (transport->remote->fetch_tags == 2)
@@ -1917,6 +1918,11 @@ static int do_fetch(struct transport *transport,
1918 goto cleanup;
1919 }
1920
1921 + if (transport->remote->follow_remote_head)
1922 + follow_remote_head = transport->remote->follow_remote_head;
1923 + else
1924 + follow_remote_head = BUILTIN_FOLLOW_REMOTE_HEAD_DFLT;
1925 +
1926 if (rs->nr) {
1927 refspec_ref_prefixes(rs, &transport_ls_refs_options.ref_prefixes);
1928 } else {
@@ -1925,7 +1931,7 @@ static int do_fetch(struct transport *transport,
1931 if (transport->remote->fetch.nr) {
1932 refspec_ref_prefixes(&transport->remote->fetch,
1933 &transport_ls_refs_options.ref_prefixes);
1928 - if (transport->remote->follow_remote_head != FOLLOW_REMOTE_NEVER)
1934 + if (follow_remote_head != FOLLOW_REMOTE_NEVER)
1935 do_set_head = 1;
1936 }
1937 if (branch && branch_has_merge_config(branch) &&
@@ -2132,7 +2138,7 @@ static int do_fetch(struct transport *transport,
2138 * Way too many cases where this can go wrong so let's just
2139 * ignore errors and fail silently for now.
2140 */
2135 - set_head(remote_refs, transport->remote);
2141 + set_head(remote_refs, transport->remote, follow_remote_head);
2142 }
2143
2144 cleanup:
remote.h
+8 -6
@@ -62,12 +62,14 @@ struct remote_state {
62 void remote_state_clear(struct remote_state *remote_state);
63 struct remote_state *remote_state_new(void);
64
65 - enum follow_remote_head_settings {
66 - FOLLOW_REMOTE_NEVER = -1,
67 - FOLLOW_REMOTE_CREATE = 0,
68 - FOLLOW_REMOTE_WARN = 1,
69 - FOLLOW_REMOTE_ALWAYS = 2,
70 - };
65 +#define BUILTIN_FOLLOW_REMOTE_HEAD_DFLT FOLLOW_REMOTE_CREATE
66 +enum follow_remote_head_settings {
67 + FOLLOW_REMOTE_UNCONFIGURED = 0,
68 + FOLLOW_REMOTE_NEVER,
69 + FOLLOW_REMOTE_CREATE,
70 + FOLLOW_REMOTE_WARN,
71 + FOLLOW_REMOTE_ALWAYS,
72 +};
73
74 struct remote {
75 struct hashmap_entry ent;