From mboxrd@z Thu Jan 1 00:00:00 1970 From: Fredrik Medley Subject: [PATCH] upload-pack: Optionally allow fetching reachable sha1 Date: Sun, 3 May 2015 00:01:15 +0200 Message-ID: <1430604075-5951-1-git-send-email-fredrik.medley@gmail.com> Cc: Fredrik Medley , Christian Halstrick , Dan Johnson , Jeff King , Jonathan Nieder , Duy Nguyen , Junio C Hamano To: git@vger.kernel.org X-From: git-owner@vger.kernel.org Sun May 03 00:01:40 2015 Return-path: Envelope-to: gcvg-git-2@plane.gmane.org Received: from vger.kernel.org ([209.132.180.67]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1YofTd-0002ai-Fa for gcvg-git-2@plane.gmane.org; Sun, 03 May 2015 00:01:38 +0200 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754940AbbEBWBd (ORCPT ); Sat, 2 May 2015 18:01:33 -0400 Received: from mail-la0-f41.google.com ([209.85.215.41]:34707 "EHLO mail-la0-f41.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752883AbbEBWBc (ORCPT ); Sat, 2 May 2015 18:01:32 -0400 Received: by laat2 with SMTP id t2so83191670laa.1 for ; Sat, 02 May 2015 15:01:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=8Waw1ABoElitP7zrPYvCrv526uJ2iGhm/Ko/nLxrUoM=; b=oVjJF0TBxw9EQq29v3iIy+KHgD9jhTGljSmniDxeXg/yQQYtUj+XxFu29n8grS6xW+ kk41IgOAEwmMC6AHOrnS8g5pK6MmLHRNat7C37vnh6j2KQCyE8MH7N0FZCgTgxRATt0C tKEwR/PeTyarVc1kHvYTO/QExPm5m6SjtfPQXTsa/vLaozfZzIzq/40DOqz9sgpMi9bk dSHt9fektjUmlCQcU+zNPE47Ij+TEBCs17sElfBHwITlKLR3IG9dxwMFBUbWGvNz9N0/ eYtrHrccy9puqouxlJiBQu5iX0lwXjN9Zde64Up53XsGN2Fd1Qdqf2+4BewrBkfahRl/ 4S1A== X-Received: by 10.112.13.6 with SMTP id d6mr12083121lbc.117.1430604090406; Sat, 02 May 2015 15:01:30 -0700 (PDT) Received: from localhost.localdomain (c83-252-232-146.bredband.comhem.se. [83.252.232.146]) by mx.google.com with ESMTPSA id z2sm2287118lae.20.2015.05.02.15.01.29 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sat, 02 May 2015 15:01:29 -0700 (PDT) X-Mailer: git-send-email 2.4.0 Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org Archived-At: For you who don't remember the email discussion, look through the references. Since before, it is allowed to ask for a sha1, but most git servers refuse the request[1]. This patch is based on a suggested location for implementation[2] which has been updated according to ideas in the reply[3]. [1] http://thread.gmane.org/gmane.comp.version-control.git/257809 [2] http://thread.gmane.org/gmane.comp.version-control.git/258002 [3] http://thread.gmane.org/gmane.comp.version-control.git/258080 With uploadpack.allowreachablesha1inwant configuration option set, "git fetch" can make a request with a "want" line that names an object that has not been advertised (likely to have been obtained out of band or from a submodule pointer). Only objects reachable from the branch tips, hidden by transfer.hiderefs or not, will be processed. Signed-off-by: Fredrik Medley --- Documentation/config.txt | 6 ++++++ fetch-pack.c | 9 ++++++-- t/t5516-fetch-push.sh | 55 ++++++++++++++++++++++++++++++++++++++++++++++++ upload-pack.c | 13 +++++++++--- 4 files changed, 78 insertions(+), 5 deletions(-) diff --git a/Documentation/config.txt b/Documentation/config.txt index 2e5ceaf..76cd713 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -2538,6 +2538,12 @@ uploadpack.allowtipsha1inwant:: of a hidden ref (by default, such a request is rejected). see also `uploadpack.hideRefs`. +uploadpack.allowreachablesha1inwant:: + Allow `upload-pack` to accept a fetch request that asks for an + object that is reachable from any ref tip. However, note that + calculating object reachability is computationally expensive. + 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 diff --git a/fetch-pack.c b/fetch-pack.c index 48526aa..fb01b6c 100644 --- a/fetch-pack.c +++ b/fetch-pack.c @@ -43,7 +43,7 @@ static int marked; #define MAX_IN_VAIN 256 static struct prio_queue rev_list = { compare_commits_by_commit_date }; -static int non_common_revs, multi_ack, use_sideband, allow_tip_sha1_in_want; +static int non_common_revs, multi_ack, use_sideband, allow_tip_sha1_in_want, allow_reachable_sha1_in_want; static void rev_list_push(struct commit *commit, int mark) { @@ -542,7 +542,7 @@ static void filter_refs(struct fetch_pack_args *args, } /* Append unmatched requests to the list */ - if (allow_tip_sha1_in_want) { + if (allow_tip_sha1_in_want || allow_reachable_sha1_in_want) { for (i = 0; i < nr_sought; i++) { unsigned char sha1[20]; @@ -823,6 +823,11 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args, fprintf(stderr, "Server supports allow-tip-sha1-in-want\n"); allow_tip_sha1_in_want = 1; } + if (server_supports("allow-reachable-sha1-in-want")) { + if (args->verbose) + fprintf(stderr, "Server supports allow-reachable-sha1-in-want\n"); + allow_reachable_sha1_in_want = 1; + } if (!server_supports("thin-pack")) args->use_thin_pack = 0; if (!server_supports("no-progress")) diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh index 8a5f236..01fabfb 100755 --- a/t/t5516-fetch-push.sh +++ b/t/t5516-fetch-push.sh @@ -1120,6 +1120,61 @@ test_expect_success 'fetch exact SHA1' ' ) ' +for configallowtipsha1inwant in true false +do + test_expect_success "shallow fetch reachable SHA1 (but not a ref), allowtipsha1inwant=$configallowtipsha1inwant" ' + mk_empty testrepo && + ( + cd testrepo && + git config uploadpack.allowtipsha1inwant $configallowtipsha1inwant && + git commit --allow-empty -m foo && + git commit --allow-empty -m bar + ) && + SHA1=`git --git-dir=testrepo/.git rev-parse HEAD^` && + mk_empty shallow && + ( + cd shallow && + test_must_fail git fetch --depth=1 ../testrepo/.git $SHA1 && + git --git-dir=../testrepo/.git config uploadpack.allowreachablesha1inwant true && + git fetch --depth=1 ../testrepo/.git $SHA1 && + git cat-file commit $SHA1 >/dev/null + ) + ' + + test_expect_success "deny fetch unreachable SHA1, allowtipsha1inwant=$configallowtipsha1inwant" ' + mk_empty testrepo && + ( + cd testrepo && + git config uploadpack.allowtipsha1inwant $configallowtipsha1inwant && + git commit --allow-empty -m foo && + git commit --allow-empty -m bar && + git commit --allow-empty -m xyz + ) + SHA1_1=`git --git-dir=testrepo/.git rev-parse HEAD^^` && + SHA1_2=`git --git-dir=testrepo/.git rev-parse HEAD^` && + SHA1_3=`git --git-dir=testrepo/.git rev-parse HEAD` && + ( + cd testrepo && + git reset --hard $SHA1_2 && + git cat-file commit $SHA1_3 >/dev/null && + git cat-file commit $SHA1_3 >/dev/null + ) && + mk_empty shallow && + ( + cd shallow && + test_must_fail git fetch ../testrepo/.git $SHA1_3 && + test_must_fail git fetch ../testrepo/.git $SHA1_1 && + git --git-dir=../testrepo/.git config uploadpack.allowreachablesha1inwant true && + git fetch ../testrepo/.git $SHA1_1 && + git cat-file commit $SHA1_1 >/dev/null && + test_must_fail git cat-file commit $SHA1_2 >/dev/null && + git fetch ../testrepo/.git $SHA1_2 && + git cat-file commit $SHA1_2 >/dev/null && + test_must_fail git fetch ../testrepo/.git $SHA1_3 + ) + ' +done + test_expect_success 'fetch follows tags by default' ' mk_test testrepo heads/master && rm -fr src dst && diff --git a/upload-pack.c b/upload-pack.c index aa84576..2e704d6 100644 --- a/upload-pack.c +++ b/upload-pack.c @@ -36,6 +36,7 @@ static int no_done; static int use_thin_pack, use_ofs_delta, use_include_tag; static int no_progress, daemon_mode; static int allow_tip_sha1_in_want; +static int allow_reachable_sha1_in_want; static int shallow_nr; static struct object_array have_obj; static struct object_array want_obj; @@ -443,7 +444,7 @@ static int get_common_commits(void) static int is_our_ref(struct object *o) { return o->flags & - ((allow_tip_sha1_in_want ? HIDDEN_REF : 0) | OUR_REF); + (((allow_tip_sha1_in_want || allow_reachable_sha1_in_want) ? HIDDEN_REF : 0) | OUR_REF); } static void check_non_tip(void) @@ -456,8 +457,11 @@ static void check_non_tip(void) char namebuf[42]; /* ^ + SHA-1 + LF */ int i; - /* In the normal in-process case non-tip request can never happen */ - if (!stateless_rpc) + /* + * In the normal in-process case without + * uploadpack.allowreachablesha1inwant, non-tip requests can never happen. + */ + if (!stateless_rpc && !allow_reachable_sha1_in_want) goto error; cmd.argv = argv; @@ -728,6 +732,7 @@ static int send_ref(const char *refname, const unsigned char *sha1, int flag, vo sha1_to_hex(sha1), refname_nons, 0, capabilities, allow_tip_sha1_in_want ? " allow-tip-sha1-in-want" : "", + allow_reachable_sha1_in_want ? " allow-reachable-sha1-in-want" : "", stateless_rpc ? " no-done" : "", symref_info.buf, git_user_agent_sanitized()); @@ -789,6 +794,8 @@ static int upload_pack_config(const char *var, const char *value, void *unused) { if (!strcmp("uploadpack.allowtipsha1inwant", var)) allow_tip_sha1_in_want = git_config_bool(var, value); + else if (!strcmp("uploadpack.allowreachablesha1inwant", var)) + allow_reachable_sha1_in_want = git_config_bool(var, value); else if (!strcmp("uploadpack.keepalive", var)) { keepalive = git_config_int(var, value); if (!keepalive) -- 1.9.1