push: don't fetch commit object when checking existence
If we're checking to see whether to tell the user to do a fetch before pushing there's no need for us to actually fetch the object from the remote if the clone is partial. Because the promisor doesn't do negotiation actually trying to do the fetch of the new head can be very expensive as it will try and include history that we already have and it just results in rejecting the push with a different message, and in behavior that is different to a clone that is not partial. Signed-off-by: Tom Hughes <tom@compton.nu> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Tom Hughes committed
May 22, 2024 at 21:15 UTC
6549c41ead833c8d8c4098806a29399433065516
2 files changed
+20
-1
remote.c
+1
-1
@@ -1773,7 +1773,7 @@ void set_ref_status_for_push(struct ref *remote_refs, int send_mirror,
1773
if (!reject_reason && !ref->deletion && !is_null_oid(&ref->old_oid)) {
1774
if (starts_with(ref->name, "refs/tags/"))
1775
reject_reason = REF_STATUS_REJECT_ALREADY_EXISTS;
1776
- else if (!repo_has_object_file(the_repository, &ref->old_oid))
1776
+ else if (!repo_has_object_file_with_flags(the_repository, &ref->old_oid, OBJECT_INFO_SKIP_FETCH_OBJECT))
1777
reject_reason = REF_STATUS_REJECT_FETCH_FIRST;
1778
else if (!lookup_commit_reference_gently(the_repository, &ref->old_oid, 1) ||
1779
!lookup_commit_reference_gently(the_repository, &ref->new_oid, 1))
t/t0410-partial-clone.sh
+19
@@ -689,6 +689,25 @@ test_expect_success 'lazy-fetch when accessing object not in the_repository' '
689
! grep "[?]$FILE_HASH" out
690
'
691
692
+test_expect_success 'push should not fetch new commit objects' '
693
+ rm -rf server client &&
694
+ test_create_repo server &&
695
+ test_config -C server uploadpack.allowfilter 1 &&
696
+ test_config -C server uploadpack.allowanysha1inwant 1 &&
697
+ test_commit -C server server1 &&
698
+
699
+ git clone --filter=blob:none "file://$(pwd)/server" client &&
700
+ test_commit -C client client1 &&
701
+
702
+ test_commit -C server server2 &&
703
+ COMMIT=$(git -C server rev-parse server2) &&
704
+
705
+ test_must_fail git -C client push 2>err &&
706
+ grep "fetch first" err &&
707
+ git -C client rev-list --objects --missing=print "$COMMIT" >objects &&
708
+ grep "^[?]$COMMIT" objects
709
+'
710
+
711
. "$TEST_DIRECTORY"/lib-httpd.sh
712
start_httpd
713