@@ -18,17 +18,31 @@ struct tracking {
1818 int matches ;
1919};
2020
21+ struct find_tracked_branch_cb {
22+ struct tracking * tracking ;
23+ struct string_list ambiguous_remotes ;
24+ };
25+
2126static int find_tracked_branch (struct remote * remote , void * priv )
2227{
23- struct tracking * tracking = priv ;
28+ struct find_tracked_branch_cb * ftb = priv ;
29+ struct tracking * tracking = ftb -> tracking ;
2430
2531 if (!remote_find_tracking (remote , & tracking -> spec )) {
26- if (++ tracking -> matches == 1 ) {
32+ switch (++ tracking -> matches ) {
33+ case 1 :
2734 string_list_append (tracking -> srcs , tracking -> spec .src );
2835 tracking -> remote = remote -> name ;
29- } else {
36+ break ;
37+ case 2 :
38+ /* there are at least two remotes; backfill the first one */
39+ string_list_append (& ftb -> ambiguous_remotes , tracking -> remote );
40+ /* fall through */
41+ default :
42+ string_list_append (& ftb -> ambiguous_remotes , remote -> name );
3043 free (tracking -> spec .src );
3144 string_list_clear (tracking -> srcs , 0 );
45+ break ;
3246 }
3347 tracking -> spec .src = NULL ;
3448 }
@@ -232,6 +246,10 @@ static void setup_tracking(const char *new_ref, const char *orig_ref,
232246 struct tracking tracking ;
233247 struct string_list tracking_srcs = STRING_LIST_INIT_DUP ;
234248 int config_flags = quiet ? 0 : BRANCH_CONFIG_VERBOSE ;
249+ struct find_tracked_branch_cb ftb_cb = {
250+ .tracking = & tracking ,
251+ .ambiguous_remotes = STRING_LIST_INIT_DUP ,
252+ };
235253
236254 if (!track )
237255 BUG ("asked to set up tracking, but tracking is disallowed" );
@@ -240,7 +258,7 @@ static void setup_tracking(const char *new_ref, const char *orig_ref,
240258 tracking .spec .dst = (char * )orig_ref ;
241259 tracking .srcs = & tracking_srcs ;
242260 if (track != BRANCH_TRACK_INHERIT )
243- for_each_remote (find_tracked_branch , & tracking );
261+ for_each_remote (find_tracked_branch , & ftb_cb );
244262 else if (inherit_tracking (& tracking , orig_ref ))
245263 goto cleanup ;
246264
@@ -255,9 +273,39 @@ static void setup_tracking(const char *new_ref, const char *orig_ref,
255273 goto cleanup ;
256274 }
257275
258- if (tracking .matches > 1 )
259- die (_ ("not tracking: ambiguous information for ref %s" ),
260- orig_ref );
276+ if (tracking .matches > 1 ) {
277+ int status = die_message (_ ("not tracking: ambiguous information for ref '%s'" ),
278+ orig_ref );
279+ if (advice_enabled (ADVICE_AMBIGUOUS_FETCH_REFSPEC )) {
280+ struct strbuf remotes_advice = STRBUF_INIT ;
281+ struct string_list_item * item ;
282+
283+ for_each_string_list_item (item , & ftb_cb .ambiguous_remotes )
284+ /*
285+ * TRANSLATORS: This is a line listing a remote with duplicate
286+ * refspecs in the advice message below. For RTL languages you'll
287+ * probably want to swap the "%s" and leading " " space around.
288+ */
289+ strbuf_addf (& remotes_advice , _ (" %s\n" ), item -> string );
290+
291+ /*
292+ * TRANSLATORS: The second argument is a \n-delimited list of
293+ * duplicate refspecs, composed above.
294+ */
295+ advise (_ ("There are multiple remotes whose fetch refspecs map to the remote\n"
296+ "tracking ref '%s':\n"
297+ "%s"
298+ "\n"
299+ "This is typically a configuration error.\n"
300+ "\n"
301+ "To support setting up tracking branches, ensure that\n"
302+ "different remotes' fetch refspecs map into different\n"
303+ "tracking namespaces." ), orig_ref ,
304+ remotes_advice .buf );
305+ strbuf_release (& remotes_advice );
306+ }
307+ exit (status );
308+ }
261309
262310 if (tracking .srcs -> nr < 1 )
263311 string_list_append (tracking .srcs , orig_ref );
@@ -267,6 +315,7 @@ static void setup_tracking(const char *new_ref, const char *orig_ref,
267315
268316cleanup :
269317 string_list_clear (& tracking_srcs , 0 );
318+ string_list_clear (& ftb_cb .ambiguous_remotes , 0 );
270319}
271320
272321int read_branch_desc (struct strbuf * buf , const char * branch_name )
0 commit comments