@@ -104,7 +104,8 @@ static struct string_list negotiation_include = STRING_LIST_INIT_NODUP;
104104
105105struct fetch_config {
106106 enum display_format display_format ;
107- enum follow_remote_head_settings follow_remote_head ;
107+ char * follow_remote_head_raw ;
108+ int follow_remote_head_seen ;
108109 int all ;
109110 int prune ;
110111 int prune_tags ;
@@ -212,24 +213,31 @@ static int git_fetch_config(const char *k, const char *v,
212213 }
213214
214215 if (!strcmp (k , "fetch.followremotehead" )) {
215- if (!v )
216- return config_error_nonbool (k );
217- else if (!strcmp (v , "never" ))
218- fetch_config -> follow_remote_head = FOLLOW_REMOTE_NEVER ;
219- else if (!strcmp (v , "create" ))
220- fetch_config -> follow_remote_head = FOLLOW_REMOTE_CREATE ;
221- else if (!strcmp (v , "warn" ))
222- fetch_config -> follow_remote_head = FOLLOW_REMOTE_WARN ;
223- else if (!strcmp (v , "always" ))
224- fetch_config -> follow_remote_head = FOLLOW_REMOTE_ALWAYS ;
225- else
226- warning (_ ("unrecognized fetch.followRemoteHEAD value '%s' ignored" ), v );
216+ free (fetch_config -> follow_remote_head_raw );
217+ fetch_config -> follow_remote_head_raw = xstrdup_or_null (v );
218+ fetch_config -> follow_remote_head_seen = 1 ;
227219 return 0 ;
228220 }
229221
230222 return git_default_config (k , v , ctx , cb );
231223}
232224
225+ static enum follow_remote_head_settings get_follow_remote_head (const char * setting )
226+ {
227+ if (!setting )
228+ die (_ ("missing value for 'fetch.followRemoteHEAD'" ));
229+ else if (!strcmp (setting , "never" ))
230+ return FOLLOW_REMOTE_NEVER ;
231+ else if (!strcmp (setting , "create" ))
232+ return FOLLOW_REMOTE_CREATE ;
233+ else if (!strcmp (setting , "warn" ))
234+ return FOLLOW_REMOTE_WARN ;
235+ else if (!strcmp (setting , "always" ))
236+ return FOLLOW_REMOTE_ALWAYS ;
237+ warning (_ ("unrecognized fetch.followRemoteHEAD value '%s' ignored" ), setting );
238+ return BUILTIN_FOLLOW_REMOTE_HEAD_DFLT ;
239+ }
240+
233241static int parse_refmap_arg (const struct option * opt , const char * arg , int unset )
234242{
235243 BUG_ON_OPT_NEG (unset );
@@ -1978,11 +1986,10 @@ static int do_fetch(struct transport *transport,
19781986 TRANSPORT_LS_REFS_OPTIONS_INIT ;
19791987 struct fetch_head fetch_head = { 0 };
19801988 struct strbuf err = STRBUF_INIT ;
1981- int do_set_head = 0 ;
19821989 struct ref_update_display_info_array display_array = { 0 };
19831990 struct strmap rejected_refs = STRMAP_INIT ;
19841991 int summary_width = 0 ;
1985- int follow_remote_head ;
1992+ int follow_remote_head = FOLLOW_REMOTE_NEVER ;
19861993
19871994 if (tags == TAGS_DEFAULT ) {
19881995 if (transport -> remote -> fetch_tags == 2 )
@@ -1998,22 +2005,6 @@ static int do_fetch(struct transport *transport,
19982005 goto cleanup ;
19992006 }
20002007
2001- /*
2002- * NEEDSWORK: By the time this function executes, we have already parsed
2003- * all such followRemoteHEAD values from the external configuration,
2004- * potentially emitting warning messages for bogus values. Ideally, if
2005- * this fetch ends up not needing to consult these values, then git would
2006- * not ever output a value warning. (eg: when pulling from a URL directly -
2007- * rather than a configured remote, or when a remote's followRemoteHEAD
2008- * overrides the fallback fetch setting)
2009- */
2010- if (transport -> remote -> follow_remote_head )
2011- follow_remote_head = transport -> remote -> follow_remote_head ;
2012- else if (config -> follow_remote_head )
2013- follow_remote_head = config -> follow_remote_head ;
2014- else
2015- follow_remote_head = BUILTIN_FOLLOW_REMOTE_HEAD_DFLT ;
2016-
20172008 if (rs -> nr ) {
20182009 refspec_ref_prefixes (rs , & transport_ls_refs_options .ref_prefixes );
20192010 } else {
@@ -2022,8 +2013,16 @@ static int do_fetch(struct transport *transport,
20222013 if (transport -> remote -> fetch .nr ) {
20232014 refspec_ref_prefixes (& transport -> remote -> fetch ,
20242015 & transport_ls_refs_options .ref_prefixes );
2025- if (follow_remote_head != FOLLOW_REMOTE_NEVER )
2026- do_set_head = 1 ;
2016+ /*
2017+ * See remote.c's handling of remote.<name>.followRemoteHEAD
2018+ * for the analogous, still-unresolved case.
2019+ */
2020+ if (transport -> remote -> follow_remote_head )
2021+ follow_remote_head = transport -> remote -> follow_remote_head ;
2022+ else if (config -> follow_remote_head_seen )
2023+ follow_remote_head = get_follow_remote_head (config -> follow_remote_head_raw );
2024+ else
2025+ follow_remote_head = BUILTIN_FOLLOW_REMOTE_HEAD_DFLT ;
20272026 }
20282027 if (branch && branch_has_merge_config (branch ) &&
20292028 !strcmp (branch -> remote_name , transport -> remote -> name )) {
@@ -2047,7 +2046,7 @@ static int do_fetch(struct transport *transport,
20472046 strvec_push (& transport_ls_refs_options .ref_prefixes ,
20482047 "refs/tags/" );
20492048
2050- if (do_set_head )
2049+ if (follow_remote_head != FOLLOW_REMOTE_NEVER )
20512050 strvec_push (& transport_ls_refs_options .ref_prefixes ,
20522051 "HEAD" );
20532052
@@ -2226,7 +2225,7 @@ static int do_fetch(struct transport *transport,
22262225 "you need to specify exactly one branch with the --set-upstream option" ));
22272226 }
22282227 }
2229- if (do_set_head ) {
2228+ if (follow_remote_head != FOLLOW_REMOTE_NEVER ) {
22302229 /*
22312230 * Way too many cases where this can go wrong so let's just
22322231 * ignore errors and fail silently for now.
@@ -2593,7 +2592,8 @@ int cmd_fetch(int argc,
25932592{
25942593 struct fetch_config config = {
25952594 .display_format = DISPLAY_FORMAT_FULL ,
2596- .follow_remote_head = FOLLOW_REMOTE_UNCONFIGURED ,
2595+ .follow_remote_head_raw = NULL ,
2596+ .follow_remote_head_seen = 0 ,
25972597 .prune = -1 ,
25982598 .prune_tags = -1 ,
25992599 .show_forced_updates = 1 ,
@@ -3051,5 +3051,6 @@ int cmd_fetch(int argc,
30513051 oidset_clear (& updated_tips );
30523052 string_list_clear (& list , 0 );
30533053 list_objects_filter_release (& filter_options );
3054+ free (config .follow_remote_head_raw );
30543055 return result ;
30553056}
0 commit comments