From patchwork Tue Aug 9 13:11:39 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Derrick Stolee X-Patchwork-Id: 12939601 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 59785C19F2D for ; Tue, 9 Aug 2022 13:11:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243509AbiHINLx (ORCPT ); Tue, 9 Aug 2022 09:11:53 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59328 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234118AbiHINLv (ORCPT ); Tue, 9 Aug 2022 09:11:51 -0400 Received: from mail-wr1-x42d.google.com (mail-wr1-x42d.google.com [IPv6:2a00:1450:4864:20::42d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 01FCF108D for ; Tue, 9 Aug 2022 06:11:50 -0700 (PDT) Received: by mail-wr1-x42d.google.com with SMTP id j15so14297190wrr.2 for ; Tue, 09 Aug 2022 06:11:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:from:to:cc; bh=acdCRj0MaKKG5SLy1KyeFYDmc9lgpHivA8g86H8W2Bc=; b=Sr3JYEznMy++BMZBfPvy/XWHnKujuyAH1tAvwfKYcsf92L+fVLzlKv4b1iYgo3VkwY vcacSRPX88B+aQ+Y3fCTgaS5igaaxcpPi3KQX/imtVW3Vi5tZXblHAeV/KujJ3a6yGQB jEUrCs0EmgSH2qBlO73kA8dFdB35kSEG2wZmPdzyaCJH5Jx5+f1l7rrPQmU+IihTC0fa KkglUfMk1yWqWtI98FgYRhq/wsIfAg+mCy2gWaf49nw9My95AZ4k10mwYJEUeNLA93+G 5tdE/5RlVd8Tl3b4NgyYrzYxgTX6ZpW46rEpK93qz4HeJRVdO+Fyj7mamj9zHgf/Tz02 v1Fg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:x-gm-message-state:from:to:cc; bh=acdCRj0MaKKG5SLy1KyeFYDmc9lgpHivA8g86H8W2Bc=; b=y3RBuEnBjQ2IKt+pu538PPGIknJPDDugf+GEMP1/SiVgLl5OJF1ZuDCaxdyBICRr/4 Fy1agQDkKnoIeh5lQTsn7EI5f1VqbvrOgzl9WqG4tDYaCXoUCgL3GV6S7/E1VBsQq76W aCWyaLjvFYEIafD5oSSZ64VA7tMUSJfIyOiiZ9oH5SLuCXcr47TaVkuqNvy/nL54cLnu QCWSpCpKE+dMxargfVjM3n5ZhJId5yZu8joOsueZiqeueerZSDZA6RTAFF/0H57O/Tlg 72rsJ2FoYRYHRl2rqMI5rr7BWJrLRZY0GGwuTtesANTS70ZwfIDM3KN2q/zx6yZcy3ob R8yw== X-Gm-Message-State: ACgBeo2xV8gTk985WoFsuTUADXfHW+CygXPJHDdyPl9eqGm9LUWYgAK/ 6gF3WCbrOQ/CAuewI0KGkn3RoYmrrBs= X-Google-Smtp-Source: AA6agR6KPjXwljAP1OVGNHxVIBy5d2Odeeec7g3Qx9MWpr7J+TThvgdW0ztbc18dJw3apzsbrY68Ig== X-Received: by 2002:adf:dd88:0:b0:21e:f3c1:eea with SMTP id x8-20020adfdd88000000b0021ef3c10eeamr14000727wrl.23.1660050708034; Tue, 09 Aug 2022 06:11:48 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id w9-20020a5d6089000000b002205b786ab3sm13610587wrt.14.2022.08.09.06.11.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Aug 2022 06:11:47 -0700 (PDT) Message-Id: <4df4a1d679a1003ccd3a4dd049bc05141831970c.1660050703.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Tue, 09 Aug 2022 13:11:39 +0000 Subject: [PATCH v3 1/5] remote-curl: add 'get' capability Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: gitster@pobox.com, me@ttaylorr.com, newren@gmail.com, avarab@gmail.com, dyroneteng@gmail.com, Johannes.Schindelin@gmx.de, szeder.dev@gmail.com, mjcheetham@outlook.com, steadmon@google.com, Derrick Stolee , Derrick Stolee Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Derrick Stolee From: Derrick Stolee A future change will want a way to download a file over HTTP(S) using the simplest of download mechanisms. We do not want to assume that the server on the other side understands anything about the Git protocol but could be a simple static web server. Create the new 'get' capability for the remote helpers which advertises that the 'get' command is avalable. A caller can send a line containing 'get ' to download the file at into the file at . Reviewed-by: Josh Steadmon Signed-off-by: Derrick Stolee --- Documentation/gitremote-helpers.txt | 9 +++++++ remote-curl.c | 28 ++++++++++++++++++++++ t/t5557-http-get.sh | 37 +++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+) create mode 100755 t/t5557-http-get.sh diff --git a/Documentation/gitremote-helpers.txt b/Documentation/gitremote-helpers.txt index 6f1e269ae43..ed8da428c98 100644 --- a/Documentation/gitremote-helpers.txt +++ b/Documentation/gitremote-helpers.txt @@ -168,6 +168,9 @@ Supported commands: 'list', 'import'. Can guarantee that when a clone is requested, the received pack is self contained and is connected. +'get':: + Can use the 'get' command to download a file from a given URI. + If a helper advertises 'connect', Git will use it if possible and fall back to another capability if the helper requests so when connecting (see the 'connect' command under COMMANDS). @@ -418,6 +421,12 @@ Supported if the helper has the "connect" capability. + Supported if the helper has the "stateless-connect" capability. +'get' :: + Downloads the file from the given `` to the given ``. If + `.temp` exists, then Git assumes that the `.temp` file is a + partial download from a previous attempt and will resume the + download from that position. + If a fatal error occurs, the program writes the error message to stderr and exits. The caller should expect that a suitable error message has been printed if the child closes the connection without diff --git a/remote-curl.c b/remote-curl.c index b8758757ece..72dfb8fb86a 100644 --- a/remote-curl.c +++ b/remote-curl.c @@ -1286,6 +1286,29 @@ static void parse_fetch(struct strbuf *buf) strbuf_reset(buf); } +static void parse_get(const char *arg) +{ + struct strbuf url = STRBUF_INIT; + struct strbuf path = STRBUF_INIT; + const char *space; + + space = strchr(arg, ' '); + + if (!space) + die(_("protocol error: expected ' ', missing space")); + + strbuf_add(&url, arg, space - arg); + strbuf_addstr(&path, space + 1); + + if (http_get_file(url.buf, path.buf, NULL)) + die(_("failed to download file at URL '%s'"), url.buf); + + strbuf_release(&url); + strbuf_release(&path); + printf("\n"); + fflush(stdout); +} + static int push_dav(int nr_spec, const char **specs) { struct child_process child = CHILD_PROCESS_INIT; @@ -1564,9 +1587,14 @@ int cmd_main(int argc, const char **argv) printf("unsupported\n"); fflush(stdout); + } else if (skip_prefix(buf.buf, "get ", &arg)) { + parse_get(arg); + fflush(stdout); + } else if (!strcmp(buf.buf, "capabilities")) { printf("stateless-connect\n"); printf("fetch\n"); + printf("get\n"); printf("option\n"); printf("push\n"); printf("check-connectivity\n"); diff --git a/t/t5557-http-get.sh b/t/t5557-http-get.sh new file mode 100755 index 00000000000..09fb0bd9a8a --- /dev/null +++ b/t/t5557-http-get.sh @@ -0,0 +1,37 @@ +#!/bin/sh + +test_description='test downloading a file by URL' + +. ./test-lib.sh + +. "$TEST_DIRECTORY"/lib-httpd.sh +start_httpd + +test_expect_success 'get by URL: 404' ' + test_when_finished "rm -f file.temp" && + url="$HTTPD_URL/none.txt" && + cat >input <<-EOF && + capabilities + get $url file1 + EOF + + test_must_fail git remote-http $url err && + test_path_is_missing file1 && + grep "failed to download file at URL" err +' + +test_expect_success 'get by URL: 200' ' + echo data >"$HTTPD_DOCUMENT_ROOT_PATH/exists.txt" && + + url="$HTTPD_URL/exists.txt" && + cat >input <<-EOF && + capabilities + get $url file2 + + EOF + + git remote-http $url X-Patchwork-Id: 12939602 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C2B65C19F2D for ; Tue, 9 Aug 2022 13:11:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243517AbiHINLz (ORCPT ); Tue, 9 Aug 2022 09:11:55 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59390 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243504AbiHINLx (ORCPT ); Tue, 9 Aug 2022 09:11:53 -0400 Received: from mail-wr1-x432.google.com (mail-wr1-x432.google.com [IPv6:2a00:1450:4864:20::432]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D757513D79 for ; Tue, 9 Aug 2022 06:11:51 -0700 (PDT) Received: by mail-wr1-x432.google.com with SMTP id z12so14265941wrs.9 for ; Tue, 09 Aug 2022 06:11:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:from:to:cc; bh=hjSXw2K7hcxJrsGK0XrsEAkQYSIrIWRaUdxf9463oJI=; b=HvEKNH781ckHFrHSkctW7K9KSxFYvcWvNyQuBTgIKPVeyOldTXhMJvsrjHvk77Wegp rSgRne9QartkoaVMa3OpnENZLyg9bAZHgwc58asYSJw3GlAO9uiT+roPYvOZ/OKoiXrW 0AY6WRXzrfUsDAzdbMuNGTANDs7D+/S+ZIqYOdfAlIX+lMwc3+m0bvAbNZFlScUwvZRB owatW07DLD43bjmbCwkEmcbOHcAZemWsZ37ksyPxKIhpm6uls6y8qw4yFcp8VahOI+x5 Zgl2IRtGtr/OlhY0/Qq4PSszwBD0BmxOoNzTZIhi+4H84cAfiM3hUOrnzxkX0iNKlV6J ChyA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:x-gm-message-state:from:to:cc; bh=hjSXw2K7hcxJrsGK0XrsEAkQYSIrIWRaUdxf9463oJI=; b=HvF7rLldLJk06+X2Zv8FvBJB0tQByCywHnD9p/d8yojOWI8DOGLIe89IV8oOtCV5Nx sNankPFYW0lsOPzF41ep7/KZzNGKJDlSLFQpsRRJNTS+TWjKc0ZuedECet8I+0odf618 mbQ5Tnb0m+C5yaQuhmEPs1h4Hu3L7vRMCelYNTViVMU4fOXs6iVQ8Ut4+Fn5ysxfw0Di J6wJpu0AbY13Wh1moZPTSqbXIj/STYJdQ/t0P3vVwt8MhIP5coulV+Sx0NmdOk6+hlbR jgSj8sXRvTmc4CX6o1emI2RVyO3MmocEYM2J2yg6uo3izwasL61y+NWOhbMp+/GFSPj/ 7v7g== X-Gm-Message-State: ACgBeo2j3rf22dcIrUQe0O5khbWGN6zEtSz9BLwHRX1kh14ribD5rF9v nUAao4twgzjMnKqDCGJWbC3R9M1dWsg= X-Google-Smtp-Source: AA6agR6Z2rkUPIa3nIq27CG+jNni9LCa9Oj7mS8Jzsm7Pn6FdnJMI0L66rXPKgJIy3rRjMI1SoR/Qw== X-Received: by 2002:adf:fc11:0:b0:220:79df:d2c4 with SMTP id i17-20020adffc11000000b0022079dfd2c4mr13934183wrr.481.1660050709734; Tue, 09 Aug 2022 06:11:49 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id n6-20020a7bcbc6000000b003a02cbf862esm16485116wmi.13.2022.08.09.06.11.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Aug 2022 06:11:48 -0700 (PDT) Message-Id: <6a6f1a04889ac475dd9c07e98f2ffc4b677e8e40.1660050703.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Tue, 09 Aug 2022 13:11:40 +0000 Subject: [PATCH v3 2/5] bundle-uri: create basic file-copy logic Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: gitster@pobox.com, me@ttaylorr.com, newren@gmail.com, avarab@gmail.com, dyroneteng@gmail.com, Johannes.Schindelin@gmx.de, szeder.dev@gmail.com, mjcheetham@outlook.com, steadmon@google.com, Derrick Stolee , Derrick Stolee Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Derrick Stolee From: Derrick Stolee Before implementing a way to fetch bundles into a repository, create the basic logic. Assume that the URI is actually a file path. Future logic will make this more careful to other protocols. For now, we also only succeed if the content at the URI is a bundle file, not a bundle list. Bundle lists will be implemented in a future change. Note that the discovery of a temporary filename is slightly racy because the odb_mkstemp() relies on the temporary file not existing. With the current implementation being limited to file copies, we could replace the copy_file() with copy_fd(). The tricky part comes in future changes that send the filename to 'git remote-https' and its 'get' capability. At that point, we need the file descriptor closed _and_ the file unlinked. If we were to keep the file descriptor open for the sake of normal file copies, then we would pollute the rest of the code for little benefit. This is especially the case because we expect that most bundle URI use will be based on HTTPS instead of file copies. Reviewed-by: Josh Steadmon Signed-off-by: Derrick Stolee --- Makefile | 1 + bundle-uri.c | 104 ++++++++++++++++++++++++++++++++++++++++++++ bundle-uri.h | 14 ++++++ t/t5557-http-get.sh | 2 + 4 files changed, 121 insertions(+) create mode 100644 bundle-uri.c create mode 100644 bundle-uri.h diff --git a/Makefile b/Makefile index 1624471badc..7d5f48069ea 100644 --- a/Makefile +++ b/Makefile @@ -906,6 +906,7 @@ LIB_OBJS += blob.o LIB_OBJS += bloom.o LIB_OBJS += branch.o LIB_OBJS += bulk-checkin.o +LIB_OBJS += bundle-uri.o LIB_OBJS += bundle.o LIB_OBJS += cache-tree.o LIB_OBJS += cbtree.o diff --git a/bundle-uri.c b/bundle-uri.c new file mode 100644 index 00000000000..b35babc36aa --- /dev/null +++ b/bundle-uri.c @@ -0,0 +1,104 @@ +#include "cache.h" +#include "bundle-uri.h" +#include "bundle.h" +#include "object-store.h" +#include "refs.h" +#include "run-command.h" + +static int find_temp_filename(struct strbuf *name) +{ + int fd; + /* + * Find a temporary filename that is available. This is briefly + * racy, but unlikely to collide. + */ + fd = odb_mkstemp(name, "bundles/tmp_uri_XXXXXX"); + if (fd < 0) { + warning(_("failed to create temporary file")); + return -1; + } + + close(fd); + unlink(name->buf); + return 0; +} + +static int copy_uri_to_file(const char *file, const char *uri) +{ + /* File-based URIs only for now. */ + return copy_file(file, uri, 0); +} + +static int unbundle_from_file(struct repository *r, const char *file) +{ + int result = 0; + int bundle_fd; + struct bundle_header header = BUNDLE_HEADER_INIT; + struct string_list_item *refname; + struct strbuf bundle_ref = STRBUF_INIT; + size_t bundle_prefix_len; + + if ((bundle_fd = read_bundle_header(file, &header)) < 0) + return 1; + + if ((result = unbundle(r, &header, bundle_fd, NULL))) + return 1; + + /* + * Convert all refs/heads/ from the bundle into refs/bundles/ + * in the local repository. + */ + strbuf_addstr(&bundle_ref, "refs/bundles/"); + bundle_prefix_len = bundle_ref.len; + + for_each_string_list_item(refname, &header.references) { + struct object_id *oid = refname->util; + struct object_id old_oid; + const char *branch_name; + int has_old; + + if (!skip_prefix(refname->string, "refs/heads/", &branch_name)) + continue; + + strbuf_setlen(&bundle_ref, bundle_prefix_len); + strbuf_addstr(&bundle_ref, branch_name); + + has_old = !read_ref(bundle_ref.buf, &old_oid); + update_ref("fetched bundle", bundle_ref.buf, oid, + has_old ? &old_oid : NULL, + REF_SKIP_OID_VERIFICATION, + UPDATE_REFS_MSG_ON_ERR); + } + + bundle_header_release(&header); + return result; +} + +int fetch_bundle_uri(struct repository *r, const char *uri) +{ + int result = 0; + struct strbuf filename = STRBUF_INIT; + + if ((result = find_temp_filename(&filename))) + goto cleanup; + + if ((result = copy_uri_to_file(filename.buf, uri))) { + warning(_("failed to download bundle from URI '%s'"), uri); + goto cleanup; + } + + if ((result = !is_bundle(filename.buf, 0))) { + warning(_("file at URI '%s' is not a bundle"), uri); + goto cleanup; + } + + if ((result = unbundle_from_file(r, filename.buf))) { + warning(_("failed to unbundle bundle from URI '%s'"), uri); + goto cleanup; + } + +cleanup: + unlink(filename.buf); + strbuf_release(&filename); + return result; +} diff --git a/bundle-uri.h b/bundle-uri.h new file mode 100644 index 00000000000..8a152f1ef14 --- /dev/null +++ b/bundle-uri.h @@ -0,0 +1,14 @@ +#ifndef BUNDLE_URI_H +#define BUNDLE_URI_H + +struct repository; + +/** + * Fetch data from the given 'uri' and unbundle the bundle data found + * based on that information. + * + * Returns non-zero if no bundle information is found at the given 'uri'. + */ +int fetch_bundle_uri(struct repository *r, const char *uri); + +#endif diff --git a/t/t5557-http-get.sh b/t/t5557-http-get.sh index 09fb0bd9a8a..76a4bbd16af 100755 --- a/t/t5557-http-get.sh +++ b/t/t5557-http-get.sh @@ -2,6 +2,8 @@ test_description='test downloading a file by URL' +TEST_PASSES_SANITIZE_LEAK=true + . ./test-lib.sh . "$TEST_DIRECTORY"/lib-httpd.sh From patchwork Tue Aug 9 13:11:41 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Derrick Stolee X-Patchwork-Id: 12939603 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2B071C25B07 for ; Tue, 9 Aug 2022 13:11:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243538AbiHINL6 (ORCPT ); Tue, 9 Aug 2022 09:11:58 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59452 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243508AbiHINLy (ORCPT ); Tue, 9 Aug 2022 09:11:54 -0400 Received: from mail-wr1-x42c.google.com (mail-wr1-x42c.google.com [IPv6:2a00:1450:4864:20::42c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1BB1C13FA8 for ; Tue, 9 Aug 2022 06:11:52 -0700 (PDT) Received: by mail-wr1-x42c.google.com with SMTP id z16so14211628wrh.12 for ; Tue, 09 Aug 2022 06:11:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:from:to:cc; bh=F5mnbe6cQVKNs5hDJq87ao07TTZJ+9EzkJCzIacIGYQ=; b=MiMwT5dJQ+CtssC5tHIAkTkqGImOikZNY+/cZm/zX+h0f0GXnzRmLVbHyb/FMzao9V +1te0cVNHQxCerWJ7sPeibFI67Xn1YXL//D3UKDN1DycLL88CPGwhGS0CG1xi/sCmI67 98AWAyWzGGB5JmxT5nJNYm9LC12c8SoTvmzOvBgpasvGf5IHkLwOYM+wNyVjavkzxnum kgC6Sg7mhlXh/WjQJdO4e+E4/+hv5wApYsmxrLLpd2NTFF+spfwSOxgj9Ka5z2topgzl EvF7s/rNq0jsYdpqPfpcWUakaJlULa1wmu9Lu8WYF9PvF8DNGTUtVWhSU36gYAxAVT65 86/w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:x-gm-message-state:from:to:cc; bh=F5mnbe6cQVKNs5hDJq87ao07TTZJ+9EzkJCzIacIGYQ=; b=uSPgygM3yTiqZHseYbHnvFq/Rkr3rxkj5FZwOQqaZNkkcAZxetcOkc901A/A71QvBB TV+VuDxizX7OueOKCZIMSVjEp3O8IHA0C1nwyk08M0u/lmiLqKOLPVDaUrQPKu902jWK OlwevN9tMgzx8xWYnAdfDjyhpNBDRuSPDdFJvMKo7fnBv8dAxOAVGNRobVqseRrTaL90 3mBCoewBNnxlarDXQbVVbhjbmjGIHJ04Khrlk5LVyOxKH95OXOKyNGvoqSkfZVjJZR33 5lvORwc0kBYK6DNFX1jT+MhqmhtxRrX7hAaBwSr83sSgCoFfUARjxx/Y0McMuMeZu6SR aVqA== X-Gm-Message-State: ACgBeo0X3KkCpA9ZW4aZtfeklcK/w/ETogdFFfrKjRXHFK2IvKXNsJE0 1MQEEyY2JwiJG18XL4hPykMk+hIiZFQ= X-Google-Smtp-Source: AA6agR6erLvgEb4oYRCBXLplOAUBr7gS4QnuJkpCp7hAibD93zvernryhwOx67stP6g/c9aM8qsJYQ== X-Received: by 2002:adf:dd88:0:b0:21e:f3c1:eea with SMTP id x8-20020adfdd88000000b0021ef3c10eeamr14000863wrl.23.1660050711038; Tue, 09 Aug 2022 06:11:51 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id a18-20020a05600c349200b003a35ec4bf4fsm16801290wmq.20.2022.08.09.06.11.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Aug 2022 06:11:50 -0700 (PDT) Message-Id: <00debaf6e77852efe1dcad4bfda5ebd5bf590ac4.1660050704.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Tue, 09 Aug 2022 13:11:41 +0000 Subject: [PATCH v3 3/5] clone: add --bundle-uri option Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: gitster@pobox.com, me@ttaylorr.com, newren@gmail.com, avarab@gmail.com, dyroneteng@gmail.com, Johannes.Schindelin@gmx.de, szeder.dev@gmail.com, mjcheetham@outlook.com, steadmon@google.com, Derrick Stolee , Derrick Stolee Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Derrick Stolee From: Derrick Stolee Cloning a remote repository is one of the most expensive operations in Git. The server can spend a lot of CPU time generating a pack-file for the client's request. The amount of data can clog the network for a long time, and the Git protocol is not resumable. For users with poor network connections or are located far away from the origin server, this can be especially painful. Add a new '--bundle-uri' option to 'git clone' to bootstrap a clone from a bundle. If the user is aware of a bundle server, then they can tell Git to bootstrap the new repository with these bundles before fetching the remaining objects from the origin server. Reviewed-by: Josh Steadmon Signed-off-by: Derrick Stolee Signed-off-by: Derrick Stolee --- Documentation/git-clone.txt | 6 ++++++ builtin/clone.c | 15 +++++++++++++++ t/t5558-clone-bundle-uri.sh | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+) create mode 100755 t/t5558-clone-bundle-uri.sh diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt index 632bd1348ea..60fedf7eb5e 100644 --- a/Documentation/git-clone.txt +++ b/Documentation/git-clone.txt @@ -323,6 +323,12 @@ or `--mirror` is given) for `host.xz:foo/.git`). Cloning into an existing directory is only allowed if the directory is empty. +--bundle-uri=:: + Before fetching from the remote, fetch a bundle from the given + `` and unbundle the data into the local repository. The refs + in the bundle will be stored under the hidden `refs/bundle/*` + namespace. + :git-clone: 1 include::urls.txt[] diff --git a/builtin/clone.c b/builtin/clone.c index c4ff4643ecd..4224d562758 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -34,6 +34,7 @@ #include "list-objects-filter-options.h" #include "hook.h" #include "bundle.h" +#include "bundle-uri.h" /* * Overall FIXMEs: @@ -77,6 +78,7 @@ static int option_filter_submodules = -1; /* unspecified */ static int config_filter_submodules = -1; /* unspecified */ static struct string_list server_options = STRING_LIST_INIT_NODUP; static int option_remote_submodules; +static const char *bundle_uri; static int recurse_submodules_cb(const struct option *opt, const char *arg, int unset) @@ -160,6 +162,8 @@ static struct option builtin_clone_options[] = { N_("any cloned submodules will use their remote-tracking branch")), OPT_BOOL(0, "sparse", &option_sparse_checkout, N_("initialize sparse-checkout file to include only files at root")), + OPT_STRING(0, "bundle-uri", &bundle_uri, + N_("uri"), N_("a URI for downloading bundles before fetching from origin remote")), OPT_END() }; @@ -1232,6 +1236,17 @@ int cmd_clone(int argc, const char **argv, const char *prefix) if (transport->smart_options && !deepen && !filter_options.choice) transport->smart_options->check_self_contained_and_connected = 1; + /* + * Before fetching from the remote, download and install bundle + * data from the --bundle-uri option. + */ + if (bundle_uri) { + /* At this point, we need the_repository to match the cloned repo. */ + repo_init(the_repository, git_dir, work_tree); + if (fetch_bundle_uri(the_repository, bundle_uri)) + warning(_("failed to fetch objects from bundle URI '%s'"), + bundle_uri); + } strvec_push(&transport_ls_refs_options.ref_prefixes, "HEAD"); refspec_ref_prefixes(&remote->fetch, diff --git a/t/t5558-clone-bundle-uri.sh b/t/t5558-clone-bundle-uri.sh new file mode 100755 index 00000000000..f709bcb729c --- /dev/null +++ b/t/t5558-clone-bundle-uri.sh @@ -0,0 +1,36 @@ +#!/bin/sh + +test_description='test fetching bundles with --bundle-uri' + +. ./test-lib.sh + +test_expect_success 'fail to clone from non-existent file' ' + test_when_finished rm -rf test && + git clone --bundle-uri="$(pwd)/does-not-exist" . test 2>err && + grep "failed to download bundle from URI" err +' + +test_expect_success 'fail to clone from non-bundle file' ' + test_when_finished rm -rf test && + echo bogus >bogus && + git clone --bundle-uri="$(pwd)/bogus" . test 2>err && + grep "is not a bundle" err +' + +test_expect_success 'create bundle' ' + git init clone-from && + git -C clone-from checkout -b topic && + test_commit -C clone-from A && + test_commit -C clone-from B && + git -C clone-from bundle create B.bundle topic +' + +test_expect_success 'clone with path bundle' ' + git clone --bundle-uri="clone-from/B.bundle" \ + clone-from clone-path && + git -C clone-path rev-parse refs/bundles/topic >actual && + git -C clone-from rev-parse topic >expect && + test_cmp expect actual +' + +test_done From patchwork Tue Aug 9 13:11:42 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Derrick Stolee X-Patchwork-Id: 12939604 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id AA9C0C19F2D for ; Tue, 9 Aug 2022 13:12:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243597AbiHINMI (ORCPT ); Tue, 9 Aug 2022 09:12:08 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59498 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243505AbiHINLz (ORCPT ); Tue, 9 Aug 2022 09:11:55 -0400 Received: from mail-wr1-x433.google.com (mail-wr1-x433.google.com [IPv6:2a00:1450:4864:20::433]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8358F13E09 for ; Tue, 9 Aug 2022 06:11:54 -0700 (PDT) Received: by mail-wr1-x433.google.com with SMTP id q30so14242005wra.11 for ; Tue, 09 Aug 2022 06:11:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:from:to:cc; bh=WmhVshfIHI4m+KlW9sjE4s6pqYnZRfj0Q+oz5Lz/vdU=; b=B2PB2nIVCtyHChP3gF1zt0rxBtKx5fg9ewebx1J1Q1moFNuwRabV/dK6CctylJgL3F zqFtkFxu/2yZG3kSFEDKj8Revx9QCiZZOVPHMUAx2oT/nN0FWIcrirlNMlLmZLhP9OKH iK3l9KPtxb/T915mJffStvBCzlmMpnYccYRuFbhgs3XUVJSr3PhJ2zgI7bEHZbJTRxwy 33S4ETPNrUws76DikQ9LJC5aJn4ajMQM2PDfOhv1YxR00+jE3t7crkonbJ7RIdfph6Me Jc2j7H5gkgkwCgtsQ/CbB5JVtfuuP2sUxsAE4FnPAkHSGCpo1W68a9Y6iYERGKVAo4Mb m8yQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:x-gm-message-state:from:to:cc; bh=WmhVshfIHI4m+KlW9sjE4s6pqYnZRfj0Q+oz5Lz/vdU=; b=7O5E8w8hgdDNnIlA0uu/A6H6EnVDSvb44632yZywMX2vpug6XEw+Ye/sp6SwJu5mJ3 8F76KP3ZmJ+Vvjg3HMgddtUNJ0X+2xt3tNMLWluSAN6L/ek/MatTDumZIluavz8n1kg7 iFJkx3j4SobuAUBFijxPikmDeWxcXha+5cNArxPRuuIvcGDfGDx7bqe4yzl90Ug7INSO HFKpII+Odq9hE8TYyz8k1D9rmH0M31ayu1Md3P/BVXxvkh3nuh+IuzdGCMsFNgEqId6+ 69yTrexJ0cToM2bWYfYzl/feDWTOjyMOw/dIohn+1t4/X4bl/C3LXAnk6cA9u63o/TET jWlA== X-Gm-Message-State: ACgBeo2nLqvMBjX2unE9Wv1grEfTodJpADSdfS0m1RDkz24z1/eoPwHT SoreEPxC3n0EigiUcyLAeEwRHpfyc4s= X-Google-Smtp-Source: AA6agR7l5gsUrJp8P3m++6khtb3lzQm/4XP7B1kAik7Jbl4SRkNtDsFHetcQqeb7yVK3Ty88mYyDqw== X-Received: by 2002:adf:f286:0:b0:21e:f0dc:3df0 with SMTP id k6-20020adff286000000b0021ef0dc3df0mr14535376wro.377.1660050712427; Tue, 09 Aug 2022 06:11:52 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id d20-20020a05600c34d400b003a545ff43c5sm5032547wmq.45.2022.08.09.06.11.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Aug 2022 06:11:51 -0700 (PDT) Message-Id: <66a1ce4045192d153d5ac66cc248ac569cac8cf6.1660050704.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Tue, 09 Aug 2022 13:11:42 +0000 Subject: [PATCH v3 4/5] bundle-uri: add support for http(s):// and file:// Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: gitster@pobox.com, me@ttaylorr.com, newren@gmail.com, avarab@gmail.com, dyroneteng@gmail.com, Johannes.Schindelin@gmx.de, szeder.dev@gmail.com, mjcheetham@outlook.com, steadmon@google.com, Derrick Stolee , Derrick Stolee Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Derrick Stolee From: Derrick Stolee The previous change created the 'git clone --bundle-uri=' option. Currently, must be a filename. Update copy_uri_to_file() to first inspect the URI for an HTTP(S) prefix and use git-remote-https as the way to download the data at that URI. Otherwise, check to see if file:// is present and modify the prefix accordingly. Reviewed-by: Josh Steadmon Signed-off-by: Derrick Stolee --- bundle-uri.c | 70 +++++++++++++++++++++++++++++++++++-- t/t5558-clone-bundle-uri.sh | 45 ++++++++++++++++++++++++ 2 files changed, 112 insertions(+), 3 deletions(-) diff --git a/bundle-uri.c b/bundle-uri.c index b35babc36aa..4a8cc74ed05 100644 --- a/bundle-uri.c +++ b/bundle-uri.c @@ -23,10 +23,74 @@ static int find_temp_filename(struct strbuf *name) return 0; } -static int copy_uri_to_file(const char *file, const char *uri) +static int download_https_uri_to_file(const char *file, const char *uri) { - /* File-based URIs only for now. */ - return copy_file(file, uri, 0); + int result = 0; + struct child_process cp = CHILD_PROCESS_INIT; + FILE *child_in = NULL, *child_out = NULL; + struct strbuf line = STRBUF_INIT; + int found_get = 0; + + strvec_pushl(&cp.args, "git-remote-https", uri, NULL); + cp.in = -1; + cp.out = -1; + + if (start_command(&cp)) + return 1; + + child_in = fdopen(cp.in, "w"); + if (!child_in) { + result = 1; + goto cleanup; + } + + child_out = fdopen(cp.out, "r"); + if (!child_out) { + result = 1; + goto cleanup; + } + + fprintf(child_in, "capabilities\n"); + fflush(child_in); + + while (!strbuf_getline(&line, child_out)) { + if (!line.len) + break; + if (!strcmp(line.buf, "get")) + found_get = 1; + } + strbuf_release(&line); + + if (!found_get) { + result = error(_("insufficient capabilities")); + goto cleanup; + } + + fprintf(child_in, "get %s %s\n\n", uri, file); + +cleanup: + if (child_in) + fclose(child_in); + if (finish_command(&cp)) + return 1; + if (child_out) + fclose(child_out); + return result; +} + +static int copy_uri_to_file(const char *filename, const char *uri) +{ + const char *out; + + if (starts_with(uri, "https:") || + starts_with(uri, "http:")) + return download_https_uri_to_file(filename, uri); + + if (skip_prefix(uri, "file://", &out)) + uri = out; + + /* Copy as a file */ + return copy_file(filename, uri, 0); } static int unbundle_from_file(struct repository *r, const char *file) diff --git a/t/t5558-clone-bundle-uri.sh b/t/t5558-clone-bundle-uri.sh index f709bcb729c..ad666a2d28a 100755 --- a/t/t5558-clone-bundle-uri.sh +++ b/t/t5558-clone-bundle-uri.sh @@ -33,4 +33,49 @@ test_expect_success 'clone with path bundle' ' test_cmp expect actual ' +test_expect_success 'clone with file:// bundle' ' + git clone --bundle-uri="file://$(pwd)/clone-from/B.bundle" \ + clone-from clone-file && + git -C clone-file rev-parse refs/bundles/topic >actual && + git -C clone-from rev-parse topic >expect && + test_cmp expect actual +' + +######################################################################### +# HTTP tests begin here + +. "$TEST_DIRECTORY"/lib-httpd.sh +start_httpd + +test_expect_success 'fail to fetch from non-existent HTTP URL' ' + test_when_finished rm -rf test && + git clone --bundle-uri="$HTTPD_URL/does-not-exist" . test 2>err && + grep "failed to download bundle from URI" err +' + +test_expect_success 'fail to fetch from non-bundle HTTP URL' ' + test_when_finished rm -rf test && + echo bogus >"$HTTPD_DOCUMENT_ROOT_PATH/bogus" && + git clone --bundle-uri="$HTTPD_URL/bogus" . test 2>err && + grep "is not a bundle" err +' + +test_expect_success 'clone HTTP bundle' ' + cp clone-from/B.bundle "$HTTPD_DOCUMENT_ROOT_PATH/B.bundle" && + + git clone --no-local --mirror clone-from \ + "$HTTPD_DOCUMENT_ROOT_PATH/fetch.git" && + + git clone --bundle-uri="$HTTPD_URL/B.bundle" \ + "$HTTPD_URL/smart/fetch.git" clone-http && + git -C clone-http rev-parse refs/bundles/topic >actual && + git -C clone-from rev-parse topic >expect && + test_cmp expect actual && + + test_config -C clone-http log.excludedecoration refs/bundle/ +' + +# Do not add tests here unless they use the HTTP server, as they will +# not run unless the HTTP dependencies exist. + test_done From patchwork Tue Aug 9 13:11:43 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Derrick Stolee X-Patchwork-Id: 12939605 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0DEE9C25B0C for ; Tue, 9 Aug 2022 13:12:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243520AbiHINMJ (ORCPT ); Tue, 9 Aug 2022 09:12:09 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59816 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243508AbiHINMG (ORCPT ); Tue, 9 Aug 2022 09:12:06 -0400 Received: from mail-wr1-x429.google.com (mail-wr1-x429.google.com [IPv6:2a00:1450:4864:20::429]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0283C13CD2 for ; Tue, 9 Aug 2022 06:11:56 -0700 (PDT) Received: by mail-wr1-x429.google.com with SMTP id h13so14286575wrf.6 for ; Tue, 09 Aug 2022 06:11:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:from:to:cc; bh=G8JreIyzcEq7/uAXxPzoccFoQb6CoOWKqrR+In2Ko/0=; b=c/UZFyh4AOw3eGq8Z59r1L1jBar9TSaacp5llrd6LdsVGqzVfBpDo3kY1Ar0rUmRjs 9Xk4966c27aTtOavBsZk1L5djCc3AG+kxrRgDROviNy6132wgIHGWYZgKXMBafe9inKB P42Yf4s9SGekfElgVCzibWog+8JE5Ld0Nrb9a8xnILMP/XuILHR7G8vTRkOGLilAuKYy cnxLYLw4MwYJXqTbwmecmcKu5bVUVlgMjjzhzNFKAnuv09tkWQ4IQIRUqV+O8Cd79MZX w2cJjVQG9VmMM4HNq+d3xcfy3rF90AaCkc40SB0xIugdwSJsesSDn54CpWZYy+Z7euPO OPzg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:x-gm-message-state:from:to:cc; bh=G8JreIyzcEq7/uAXxPzoccFoQb6CoOWKqrR+In2Ko/0=; b=2TXyIUYE3nzzxNwtt8qEFY6KXt2bdZevq5kP4x3gD+CY1yQQJ2A66+7Z14RXaa2O80 GkZnQeselglfhLSIUBve8KhEUutvwIwRwQ/+R3FsGaGzkWeZiFPLUUAYCM6x5+17uNNl C1r4sHqSZDPZs74b/rqZO7EHQGarfPPBKl93CJNoy+xftUQioWlFKDDnuWKfpggQIkIN j9GamPjDhuQ/bzT535QjZKCrw3HxrCWw93E8pTtO0acaMFOXz2qAlBWStRuMOIZrJgUu UOTd9p3oHj0EjfyMChitYlfsOj4HkjaEsWL1fslYsGaP0r5ktLsmFN3JIEb2h3bW5YFA BQDQ== X-Gm-Message-State: ACgBeo1rcobpR75fTghjHMFlmidchbsja/9KGNlfsGzm74lleo7KKG1m qtXl3KU13tO5nhDKNcYPgCZzJn+uqtw= X-Google-Smtp-Source: AA6agR4qZe9WOcbZzk1CXIGacg/td2Cm1WVFaBD+AB50tC/4FFJcI2zDIZGnmRwDbT0ij4bJDwYoZA== X-Received: by 2002:adf:ed41:0:b0:210:20a5:26c2 with SMTP id u1-20020adfed41000000b0021020a526c2mr14031029wro.603.1660050714042; Tue, 09 Aug 2022 06:11:54 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id a7-20020a056000100700b0021f0c0c62d1sm13458376wrx.13.2022.08.09.06.11.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Aug 2022 06:11:53 -0700 (PDT) Message-Id: In-Reply-To: References: Date: Tue, 09 Aug 2022 13:11:43 +0000 Subject: [PATCH v3 5/5] clone: --bundle-uri cannot be combined with --depth Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: gitster@pobox.com, me@ttaylorr.com, newren@gmail.com, avarab@gmail.com, dyroneteng@gmail.com, Johannes.Schindelin@gmx.de, szeder.dev@gmail.com, mjcheetham@outlook.com, steadmon@google.com, Derrick Stolee , Derrick Stolee Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Derrick Stolee From: Derrick Stolee A previous change added the '--bundle-uri' option, but did not check if the --depth parameter was included. Since bundles are not compatible with shallow clones, provide an error message to the user who is attempting this combination. I am leaving this as its own change, separate from the one that implements '--bundle-uri', because this is more of an advisory for the user. There is nothing wrong with bootstrapping with bundles and then fetching a shallow clone. However, that is likely going to involve too much work for the client _and_ the server. The client will download all of this bundle information containing the full history of the repository only to ignore most of it. The server will get a shallow fetch request, but with a list of haves that might cause a more painful computation of that shallow pack-file. Reviewed-by: Josh Steadmon Signed-off-by: Derrick Stolee --- Documentation/git-clone.txt | 3 ++- builtin/clone.c | 3 +++ t/t5606-clone-options.sh | 8 ++++++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt index 60fedf7eb5e..d032d971dd7 100644 --- a/Documentation/git-clone.txt +++ b/Documentation/git-clone.txt @@ -327,7 +327,8 @@ or `--mirror` is given) Before fetching from the remote, fetch a bundle from the given `` and unbundle the data into the local repository. The refs in the bundle will be stored under the hidden `refs/bundle/*` - namespace. + namespace. This option is incompatible with `--depth`, + `--shallow-since`, and `--shallow-exclude`. :git-clone: 1 include::urls.txt[] diff --git a/builtin/clone.c b/builtin/clone.c index 4224d562758..4463789680b 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -937,6 +937,9 @@ int cmd_clone(int argc, const char **argv, const char *prefix) option_no_checkout = 1; } + if (bundle_uri && deepen) + die(_("--bundle-uri is incompatible with --depth, --shallow-since, and --shallow-exclude")); + repo_name = argv[0]; path = get_repo_path(repo_name, &is_bundle); diff --git a/t/t5606-clone-options.sh b/t/t5606-clone-options.sh index 8f676d6b0c0..f6bb02ab947 100755 --- a/t/t5606-clone-options.sh +++ b/t/t5606-clone-options.sh @@ -58,6 +58,14 @@ test_expect_success 'disallows --bare with --separate-git-dir' ' ' +test_expect_success 'disallows --bundle-uri with shallow options' ' + for option in --depth=1 --shallow-since=01-01-2000 --shallow-exclude=HEAD + do + test_must_fail git clone --bundle-uri=bundle $option from to 2>err && + grep "bundle-uri is incompatible" err || return 1 + done +' + test_expect_success 'reject cloning shallow repository' ' test_when_finished "rm -rf repo" && test_must_fail git clone --reject-shallow shallow-repo out 2>err &&