@@ -18,17 +18,31 @@ struct tracking {
18
18
int matches ;
19
19
};
20
20
21
+ struct find_tracked_branch_cb {
22
+ struct tracking * tracking ;
23
+ struct string_list ambiguous_remotes ;
24
+ };
25
+
21
26
static int find_tracked_branch (struct remote * remote , void * priv )
22
27
{
23
- struct tracking * tracking = priv ;
28
+ struct find_tracked_branch_cb * ftb = priv ;
29
+ struct tracking * tracking = ftb -> tracking ;
24
30
25
31
if (!remote_find_tracking (remote , & tracking -> spec )) {
26
- if (++ tracking -> matches == 1 ) {
32
+ switch (++ tracking -> matches ) {
33
+ case 1 :
27
34
string_list_append (tracking -> srcs , tracking -> spec .src );
28
35
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 );
30
43
free (tracking -> spec .src );
31
44
string_list_clear (tracking -> srcs , 0 );
45
+ break ;
32
46
}
33
47
tracking -> spec .src = NULL ;
34
48
}
@@ -232,6 +246,10 @@ static void setup_tracking(const char *new_ref, const char *orig_ref,
232
246
struct tracking tracking ;
233
247
struct string_list tracking_srcs = STRING_LIST_INIT_DUP ;
234
248
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
+ };
235
253
236
254
if (!track )
237
255
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,
240
258
tracking .spec .dst = (char * )orig_ref ;
241
259
tracking .srcs = & tracking_srcs ;
242
260
if (track != BRANCH_TRACK_INHERIT )
243
- for_each_remote (find_tracked_branch , & tracking );
261
+ for_each_remote (find_tracked_branch , & ftb_cb );
244
262
else if (inherit_tracking (& tracking , orig_ref ))
245
263
goto cleanup ;
246
264
@@ -255,9 +273,39 @@ static void setup_tracking(const char *new_ref, const char *orig_ref,
255
273
goto cleanup ;
256
274
}
257
275
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
+ }
261
309
262
310
if (tracking .srcs -> nr < 1 )
263
311
string_list_append (tracking .srcs , orig_ref );
@@ -267,6 +315,7 @@ static void setup_tracking(const char *new_ref, const char *orig_ref,
267
315
268
316
cleanup :
269
317
string_list_clear (& tracking_srcs , 0 );
318
+ string_list_clear (& ftb_cb .ambiguous_remotes , 0 );
270
319
}
271
320
272
321
int read_branch_desc (struct strbuf * buf , const char * branch_name )
0 commit comments