Skip to content

Commit

Permalink
upload-pack: optionally allow fetching any sha1
Browse files Browse the repository at this point in the history
It seems a little silly to do a reachabilty check in the case where we
trust the user to access absolutely everything in the repository.

Also, it's racy in a distributed system -- perhaps one server
advertises a ref, but another has since had a force-push to that ref,
and perhaps the two HTTP requests end up directed to these different
servers.

Signed-off-by: David Turner <dturner@twosigma.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
novalis authored and gitster committed Nov 18, 2016
1 parent 296b847 commit f8edeaa
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 4 deletions.
5 changes: 5 additions & 0 deletions Documentation/config.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2961,6 +2961,11 @@ uploadpack.allowReachableSHA1InWant::
calculating object reachability is computationally expensive.
Defaults to `false`.

uploadpack.allowAnySHA1InWant::
Allow `upload-pack` to accept a fetch request that asks for any
object at all.
Defaults to `false`.

uploadpack.keepAlive::
When `upload-pack` has started `pack-objects`, there may be a
quiet period while `pack-objects` prepares the pack. Normally
Expand Down
6 changes: 3 additions & 3 deletions Documentation/git-fetch-pack.txt
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,9 @@ be in a separate packet, and the list must end with a flush packet.
$GIT_DIR (e.g. "HEAD", "refs/heads/master"). When
unspecified, update from all heads the remote side has.
+
If the remote has enabled the options `uploadpack.allowTipSHA1InWant` or
`uploadpack.allowReachableSHA1InWant`, they may alternatively be 40-hex
sha1s present on the remote.
If the remote has enabled the options `uploadpack.allowTipSHA1InWant`,
`uploadpack.allowReachableSHA1InWant`, or `uploadpack.allowAnySHA1InWant`,
they may alternatively be 40-hex sha1s present on the remote.

SEE ALSO
--------
Expand Down
22 changes: 22 additions & 0 deletions t/t5551-http-fetch-smart.sh
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,28 @@ test_expect_success 'test allowreachablesha1inwant with unreachable' '
test_must_fail git -C test_reachable.git fetch origin "$(git rev-parse HEAD)"
'

test_expect_success 'test allowanysha1inwant with unreachable' '
test_when_finished "rm -rf test_reachable.git; git reset --hard $(git rev-parse HEAD)" &&
#create unreachable sha
echo content >file2 &&
git add file2 &&
git commit -m two &&
git push public HEAD:refs/heads/doomed &&
git push public :refs/heads/doomed &&
server="$HTTPD_DOCUMENT_ROOT_PATH/repo.git" &&
master_sha=$(git -C "$server" rev-parse refs/heads/master) &&
git -C "$server" config uploadpack.allowreachablesha1inwant 1 &&
git init --bare test_reachable.git &&
git -C test_reachable.git remote add origin "$HTTPD_URL/smart/repo.git" &&
test_must_fail git -C test_reachable.git fetch origin "$(git rev-parse HEAD)" &&
git -C "$server" config uploadpack.allowanysha1inwant 1 &&
git -C test_reachable.git fetch origin "$(git rev-parse HEAD)"
'

test_expect_success EXPENSIVE 'http can handle enormous ref negotiation' '
(
cd "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" &&
Expand Down
10 changes: 9 additions & 1 deletion upload-pack.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ static int no_progress, daemon_mode;
#define ALLOW_TIP_SHA1 01
/* Allow request of a sha1 if it is reachable from a ref (possibly hidden ref). */
#define ALLOW_REACHABLE_SHA1 02
/* Allow request of any sha1. Implies ALLOW_TIP_SHA1 and ALLOW_REACHABLE_SHA1. */
#define ALLOW_ANY_SHA1 07
static unsigned int allow_unadvertised_object_request;
static int shallow_nr;
static struct object_array have_obj;
Expand Down Expand Up @@ -825,7 +827,8 @@ static void receive_needs(void)
sha1_to_hex(sha1_buf));
if (!(o->flags & WANTED)) {
o->flags |= WANTED;
if (!is_our_ref(o))
if (!((allow_unadvertised_object_request & ALLOW_ANY_SHA1) == ALLOW_ANY_SHA1
|| is_our_ref(o)))
has_non_tip = 1;
add_object_array(o, NULL, &want_obj);
}
Expand Down Expand Up @@ -1008,6 +1011,11 @@ static int upload_pack_config(const char *var, const char *value, void *unused)
allow_unadvertised_object_request |= ALLOW_REACHABLE_SHA1;
else
allow_unadvertised_object_request &= ~ALLOW_REACHABLE_SHA1;
} else if (!strcmp("uploadpack.allowanysha1inwant", var)) {
if (git_config_bool(var, value))
allow_unadvertised_object_request |= ALLOW_ANY_SHA1;
else
allow_unadvertised_object_request &= ~ALLOW_ANY_SHA1;
} else if (!strcmp("uploadpack.keepalive", var)) {
keepalive = git_config_int(var, value);
if (!keepalive)
Expand Down

0 comments on commit f8edeaa

Please sign in to comment.