@@ -1643,6 +1643,21 @@ static int set_head(const struct ref *remote_refs)
return result;
}
+static int uses_remote_tracking(struct transport *transport, struct refspec *rs)
+{
+ if (!remote_is_configured(transport->remote, 0))
+ return 0;
+
+ if (!rs->nr)
+ rs = &transport->remote->fetch;
+
+ for (int i = 0; i < rs->nr; i++)
+ if (rs->items[i].dst)
+ return 1;
+
+ return 0;
+}
+
static int do_fetch(struct transport *transport,
struct refspec *rs,
const struct fetch_config *config)
@@ -1712,7 +1727,10 @@ static int do_fetch(struct transport *transport,
"refs/tags/");
}
- strvec_push(&transport_ls_refs_options.ref_prefixes, "HEAD");
+ if (uses_remote_tracking(transport, rs)) {
+ must_list_refs = 1;
+ strvec_push(&transport_ls_refs_options.ref_prefixes, "HEAD");
+ }
if (must_list_refs) {
trace2_region_enter("fetch", "remote_refs", the_repository);
@@ -189,6 +189,23 @@ test_expect_success 'fetch --prune --tags with refspec prunes based on refspec'
git rev-parse sometag
'
+test_expect_success 'fetch --tags gets tags even without a configured remote' '
+ REMOTE="$(pwd)/test_tag_1" &&
+ git init test_tag_1 &&
+ (
+ cd test_tag_1 &&
+ test_commit foo
+ ) &&
+ git init test_tag_2 &&
+ (
+ cd test_tag_2 &&
+ git fetch --tags "file://$REMOTE" &&
+ echo "foo" >expect &&
+ git tag >actual &&
+ test_cmp expect actual
+ )
+'
+
test_expect_success REFFILES 'fetch --prune fails to delete branches' '
cd "$D" &&
git clone . prune-fail &&