Skip to content

Commit

Permalink
push: don't fetch commit object when checking existence
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: Junio C Hamano <[email protected]>
  • Loading branch information
tomhughes authored and gitster committed May 22, 2024
1 parent 786a3e4 commit 6549c41
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 1 deletion.
2 changes: 1 addition & 1 deletion remote.c
Original file line number Diff line number Diff line change
Expand Up @@ -1773,7 +1773,7 @@ void set_ref_status_for_push(struct ref *remote_refs, int send_mirror,
if (!reject_reason && !ref->deletion && !is_null_oid(&ref->old_oid)) {
if (starts_with(ref->name, "refs/tags/"))
reject_reason = REF_STATUS_REJECT_ALREADY_EXISTS;
else if (!repo_has_object_file(the_repository, &ref->old_oid))
else if (!repo_has_object_file_with_flags(the_repository, &ref->old_oid, OBJECT_INFO_SKIP_FETCH_OBJECT))
reject_reason = REF_STATUS_REJECT_FETCH_FIRST;
else if (!lookup_commit_reference_gently(the_repository, &ref->old_oid, 1) ||
!lookup_commit_reference_gently(the_repository, &ref->new_oid, 1))
Expand Down
19 changes: 19 additions & 0 deletions t/t0410-partial-clone.sh
Original file line number Diff line number Diff line change
Expand Up @@ -689,6 +689,25 @@ test_expect_success 'lazy-fetch when accessing object not in the_repository' '
! grep "[?]$FILE_HASH" out
'

test_expect_success 'push should not fetch new commit objects' '
rm -rf server client &&
test_create_repo server &&
test_config -C server uploadpack.allowfilter 1 &&
test_config -C server uploadpack.allowanysha1inwant 1 &&
test_commit -C server server1 &&
git clone --filter=blob:none "file://$(pwd)/server" client &&
test_commit -C client client1 &&
test_commit -C server server2 &&
COMMIT=$(git -C server rev-parse server2) &&
test_must_fail git -C client push 2>err &&
grep "fetch first" err &&
git -C client rev-list --objects --missing=print "$COMMIT" >objects &&
grep "^[?]$COMMIT" objects
'

. "$TEST_DIRECTORY"/lib-httpd.sh
start_httpd

Expand Down

0 comments on commit 6549c41

Please sign in to comment.