summaryrefslogtreecommitdiff
path: root/branch.c
diff options
context:
space:
mode:
authorLibravatar Junio C Hamano <gitster@pobox.com>2022-04-04 10:56:23 -0700
committerLibravatar Junio C Hamano <gitster@pobox.com>2022-04-04 10:56:24 -0700
commitba2452b247dfd455bccbcb04acdcfd142cb5397e (patch)
treec026f02a9e732ccbb6b5fd94b58955e7aa7d7abd /branch.c
parentMerge branch 'rc/fetch-refetch' (diff)
parenttracking branches: add advice to ambiguous refspec error (diff)
downloadtgif-ba2452b247dfd455bccbcb04acdcfd142cb5397e.tar.xz
Merge branch 'tk/ambiguous-fetch-refspec'
Give hint when branch tracking cannot be established because fetch refspecs from multiple remote repositories overlap. * tk/ambiguous-fetch-refspec: tracking branches: add advice to ambiguous refspec error
Diffstat (limited to 'branch.c')
-rw-r--r--branch.c63
1 files changed, 56 insertions, 7 deletions
diff --git a/branch.c b/branch.c
index 581afd634d..01ecb816d5 100644
--- a/branch.c
+++ b/branch.c
@@ -18,17 +18,31 @@ struct tracking {
int matches;
};
+struct find_tracked_branch_cb {
+ struct tracking *tracking;
+ struct string_list ambiguous_remotes;
+};
+
static int find_tracked_branch(struct remote *remote, void *priv)
{
- struct tracking *tracking = priv;
+ struct find_tracked_branch_cb *ftb = priv;
+ struct tracking *tracking = ftb->tracking;
if (!remote_find_tracking(remote, &tracking->spec)) {
- if (++tracking->matches == 1) {
+ switch (++tracking->matches) {
+ case 1:
string_list_append(tracking->srcs, tracking->spec.src);
tracking->remote = remote->name;
- } else {
+ break;
+ case 2:
+ /* there are at least two remotes; backfill the first one */
+ string_list_append(&ftb->ambiguous_remotes, tracking->remote);
+ /* fall through */
+ default:
+ string_list_append(&ftb->ambiguous_remotes, remote->name);
free(tracking->spec.src);
string_list_clear(tracking->srcs, 0);
+ break;
}
tracking->spec.src = NULL;
}
@@ -232,6 +246,10 @@ static void setup_tracking(const char *new_ref, const char *orig_ref,
struct tracking tracking;
struct string_list tracking_srcs = STRING_LIST_INIT_DUP;
int config_flags = quiet ? 0 : BRANCH_CONFIG_VERBOSE;
+ struct find_tracked_branch_cb ftb_cb = {
+ .tracking = &tracking,
+ .ambiguous_remotes = STRING_LIST_INIT_DUP,
+ };
if (!track)
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,
tracking.spec.dst = (char *)orig_ref;
tracking.srcs = &tracking_srcs;
if (track != BRANCH_TRACK_INHERIT)
- for_each_remote(find_tracked_branch, &tracking);
+ for_each_remote(find_tracked_branch, &ftb_cb);
else if (inherit_tracking(&tracking, orig_ref))
goto cleanup;
@@ -255,9 +273,39 @@ static void setup_tracking(const char *new_ref, const char *orig_ref,
goto cleanup;
}
- if (tracking.matches > 1)
- die(_("not tracking: ambiguous information for ref %s"),
- orig_ref);
+ if (tracking.matches > 1) {
+ int status = die_message(_("not tracking: ambiguous information for ref '%s'"),
+ orig_ref);
+ if (advice_enabled(ADVICE_AMBIGUOUS_FETCH_REFSPEC)) {
+ struct strbuf remotes_advice = STRBUF_INIT;
+ struct string_list_item *item;
+
+ for_each_string_list_item(item, &ftb_cb.ambiguous_remotes)
+ /*
+ * TRANSLATORS: This is a line listing a remote with duplicate
+ * refspecs in the advice message below. For RTL languages you'll
+ * probably want to swap the "%s" and leading " " space around.
+ */
+ strbuf_addf(&remotes_advice, _(" %s\n"), item->string);
+
+ /*
+ * TRANSLATORS: The second argument is a \n-delimited list of
+ * duplicate refspecs, composed above.
+ */
+ advise(_("There are multiple remotes whose fetch refspecs map to the remote\n"
+ "tracking ref '%s':\n"
+ "%s"
+ "\n"
+ "This is typically a configuration error.\n"
+ "\n"
+ "To support setting up tracking branches, ensure that\n"
+ "different remotes' fetch refspecs map into different\n"
+ "tracking namespaces."), orig_ref,
+ remotes_advice.buf);
+ strbuf_release(&remotes_advice);
+ }
+ exit(status);
+ }
if (tracking.srcs->nr < 1)
string_list_append(tracking.srcs, orig_ref);
@@ -267,6 +315,7 @@ static void setup_tracking(const char *new_ref, const char *orig_ref,
cleanup:
string_list_clear(&tracking_srcs, 0);
+ string_list_clear(&ftb_cb.ambiguous_remotes, 0);
}
int read_branch_desc(struct strbuf *buf, const char *branch_name)