diff --git a/builtin/fetch.c b/builtin/fetch.c index 670bf10632..2e98969504 100644 --- a/builtin/fetch.c +++ b/builtin/fetch.c @@ -2200,6 +2200,27 @@ static int do_fetch(struct transport *transport, struct ref *tags_ref_map = NULL, **tail = &tags_ref_map; find_non_local_tags(remote_refs, transaction, &tags_ref_map, &tail); + + /* + * Backfilling tags has no depth limit. If we don't commit + * the fetched references, the backfill will report no refs + * in the 'have' section of the negotiation. This can cause + * the server to send all objects. + */ + if (tags_ref_map && !atomic_fetch) { + retcode |= commit_ref_transaction(&transaction, false, + transport->remote->name, + &rejected_refs, &err); + + transaction = ref_store_transaction_begin(get_main_ref_store(the_repository), + REF_TRANSACTION_ALLOW_FAILURE, &err); + if (!transaction) { + free_refs(tags_ref_map); + retcode = -1; + goto cleanup; + } + } + if (tags_ref_map) { /* * If backfilling of tags fails then we want to tell diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh index 588cbe69d3..33ff164d5e 100755 --- a/t/t5510-fetch.sh +++ b/t/t5510-fetch.sh @@ -2108,6 +2108,22 @@ test_expect_success "backfill tags when providing a refspec" ' test_cmp expect actual ' +test_expect_success 'shallow fetch does not fetch objects again for tags' ' + test_when_finished rm -rf source target && + + git init source && + test_commit_bulk -C source 10 && + git -C source tag -a tag -m tag HEAD~2 && + root_oid=$(git -C source rev-parse HEAD~9) && + + git init target && + git -C target remote add origin ../source && + git -C target fetch --depth 5 origin && + + # Should not fetch objects beyond the pre-specified depth. + test_must_fail git -C target cat-file -e "$root_oid" +' + test_expect_success REFFILES "FETCH_HEAD is updated even if ref updates fail" ' test_when_finished rm -rf base repo &&