From patchwork Tue Apr 6 18:47:46 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Derrick Stolee X-Patchwork-Id: 12185713 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id CBF22C433ED for ; Tue, 6 Apr 2021 18:47:55 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 960B5613BD for ; Tue, 6 Apr 2021 18:47:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240418AbhDFSsC (ORCPT ); Tue, 6 Apr 2021 14:48:02 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43914 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233898AbhDFSsC (ORCPT ); Tue, 6 Apr 2021 14:48:02 -0400 Received: from mail-wr1-x435.google.com (mail-wr1-x435.google.com [IPv6:2a00:1450:4864:20::435]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E34ABC06174A for ; Tue, 6 Apr 2021 11:47:53 -0700 (PDT) Received: by mail-wr1-x435.google.com with SMTP id b9so7417211wrs.1 for ; Tue, 06 Apr 2021 11:47:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=Llo0Of7xrxXb6L4qe3wjXKvb7OepjL9FntDDDajZ5Mw=; b=DMyp7iRDR6qii+ndDYKda85Lrw1I11PqvwyMBEIbUV6Q0vueUN42ry5CdZEDy6AYN6 R01gm+CbZgiXGDrfvgvSVfH1+LetRPQX06MY7ja/ka9FCS7lUnEHNce/81zeq32ad60p fAqW9CPSF8/mfVZZbBwRlXtlBugYkGXD/qwYb2zSwLKdm/Cnqk/CiwL1MtBzT3VAziDe q+VCiPosmdDoLNwO5oXeGTduGR2UDr9jMDsx+ldWIyi2akk5Z5VtyJWIj5mfyefavX2Z Gt7c/ydfzUnEg/SkuFN1b4VNCtvbnZ4CUY58Q4Y6a11pgV47fepV/vFz3YC0lR1lWBOz OjOw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=Llo0Of7xrxXb6L4qe3wjXKvb7OepjL9FntDDDajZ5Mw=; b=ea9AVDGQ+QisottLuOMCW4WTsDSHW7Jbh8Bz6wDdpmTOuoMVWhv1MU/oBoGa38ujqR BodFwghl/c/JkjmeUDxydSKTL5wTQLvZDcOYkxpHCZL6NGIeHnUnetX+2F9+XT4WCFHb 57tqzuUD/kZI1rpsPfewlIAq0pw/zugOVuPC34vPjk2KAeee2GEjcbhVFabQ1yfYAjEb qJTlGOY4NSjSRPpqfFnBlphPgJSPJzDxR3+8hhtDuYwAjbjhTGPb8Gkyl6TVRytsgwWO x3Cq5V4hEjbnhGjriPZDxCgO/2tkFA6HKJt8apkJrmjNj7zB6iLUS4NMxvH073ZUe1x1 Li7Q== X-Gm-Message-State: AOAM530H7K5qyF5lbLKT0g2smc6ZWcHItLYv2B8tmjnTlCFHLHZtH2iN ihTJKwB4b4EnnK9gxDBBeDezy17buIs= X-Google-Smtp-Source: ABdhPJwp9Ga7oNmi7zd/9E17vzxh9jH1+lBGS+vmBw7Iqmld3bvvb9PuDjZFHVlrfdwVcCxbQYAjPA== X-Received: by 2002:adf:f8c2:: with SMTP id f2mr5089623wrq.194.1617734872603; Tue, 06 Apr 2021 11:47:52 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id o24sm3718380wmr.26.2021.04.06.11.47.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Apr 2021 11:47:52 -0700 (PDT) Message-Id: <5aa0cb06c3f2e31a51bb6747fa84de69c0c1212f.1617734870.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Tue, 06 Apr 2021 18:47:46 +0000 Subject: [PATCH v2 1/5] maintenance: simplify prefetch logic Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: tom.saeger@oracle.com, gitster@pobox.com, sunshine@sunshineco.com, Derrick Stolee , Derrick Stolee , Derrick Stolee Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Derrick Stolee From: Derrick Stolee The previous logic filled a string list with the names of each remote, but instead we could simply run the appropriate 'git fetch' data directly in the remote iterator. Do this for reduced code size, but also because it sets up an upcoming change to use the remote's refspec. This data is accessible from the 'struct remote' data that is now accessible in fetch_remote(). Signed-off-by: Derrick Stolee --- builtin/gc.c | 33 ++++++++------------------------- 1 file changed, 8 insertions(+), 25 deletions(-) diff --git a/builtin/gc.c b/builtin/gc.c index ef7226d7bca4..fa8128de9ae1 100644 --- a/builtin/gc.c +++ b/builtin/gc.c @@ -873,55 +873,38 @@ static int maintenance_task_commit_graph(struct maintenance_run_opts *opts) return 0; } -static int fetch_remote(const char *remote, struct maintenance_run_opts *opts) +static int fetch_remote(struct remote *remote, void *cbdata) { + struct maintenance_run_opts *opts = cbdata; struct child_process child = CHILD_PROCESS_INIT; child.git_cmd = 1; - strvec_pushl(&child.args, "fetch", remote, "--prune", "--no-tags", + strvec_pushl(&child.args, "fetch", remote->name, "--prune", "--no-tags", "--no-write-fetch-head", "--recurse-submodules=no", "--refmap=", NULL); if (opts->quiet) strvec_push(&child.args, "--quiet"); - strvec_pushf(&child.args, "+refs/heads/*:refs/prefetch/%s/*", remote); + strvec_pushf(&child.args, "+refs/heads/*:refs/prefetch/%s/*", remote->name); return !!run_command(&child); } -static int append_remote(struct remote *remote, void *cbdata) -{ - struct string_list *remotes = (struct string_list *)cbdata; - - string_list_append(remotes, remote->name); - return 0; -} - static int maintenance_task_prefetch(struct maintenance_run_opts *opts) { - int result = 0; - struct string_list_item *item; - struct string_list remotes = STRING_LIST_INIT_DUP; - git_config_set_multivar_gently("log.excludedecoration", "refs/prefetch/", "refs/prefetch/", CONFIG_FLAGS_FIXED_VALUE | CONFIG_FLAGS_MULTI_REPLACE); - if (for_each_remote(append_remote, &remotes)) { - error(_("failed to fill remotes")); - result = 1; - goto cleanup; + if (for_each_remote(fetch_remote, opts)) { + error(_("failed to prefetch remotes")); + return 1; } - for_each_string_list_item(item, &remotes) - result |= fetch_remote(item->string, opts); - -cleanup: - string_list_clear(&remotes, 0); - return result; + return 0; } static int maintenance_task_gc(struct maintenance_run_opts *opts) From patchwork Tue Apr 6 18:47:47 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Derrick Stolee X-Patchwork-Id: 12185715 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 59423C433B4 for ; Tue, 6 Apr 2021 18:47:56 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 27E37613D2 for ; Tue, 6 Apr 2021 18:47:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240485AbhDFSsD (ORCPT ); Tue, 6 Apr 2021 14:48:03 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43918 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240251AbhDFSsC (ORCPT ); Tue, 6 Apr 2021 14:48:02 -0400 Received: from mail-wm1-x329.google.com (mail-wm1-x329.google.com [IPv6:2a00:1450:4864:20::329]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7741EC06175F for ; Tue, 6 Apr 2021 11:47:54 -0700 (PDT) Received: by mail-wm1-x329.google.com with SMTP id t5-20020a1c77050000b029010e62cea9deso7819503wmi.0 for ; Tue, 06 Apr 2021 11:47:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=PgJ0YgR2NLW/QaUBFc2FgMQq0xZYgM9FeOj+wD03FLg=; b=iHsH1ucyOGEQAoDxt+F4PfFwNTeIRxMJ7G/SB3bLb4VJNGYKn5juTFmevv4oRPxzUP h2Wx/AoGx+BV+4hzYOmnQl1sgEQlMZyV+iaT3RACV0Ts4QDsEWBXCx+rEamsDGnO5sV5 BqDgXgRFeO98Nrkpqc00cUuLEWp8y0eAWLQgN5rdBqZjKEvjxvLSuNHacMEaMq03zKon b+O70eafeCmTTG/e0uvu7CquWSZETwdTueKcdWTswnC2x+0HHvPLxBHGANAdDfc15PTN jxwzOz6Ej4ZY66bYwAnrO/3Vy+fYCadsFxKn5L7zHjuCIVdLFn8QEeZuiI12+MnJK9hH Qf2w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=PgJ0YgR2NLW/QaUBFc2FgMQq0xZYgM9FeOj+wD03FLg=; b=XEjvV85A3eFdqbku+bAvAraVJGwfjsiyifkenXw5OuSikD/hWLiRdgs5Rizv5y4Gnk zprk9E5LSd4/EgZVV/VJ/OqjEVklQRHNT/1lvZgzpbNiQ28QCZs0K2dyWjR2tXYh0ICt JtF0c+Kzj6/ssa2X9JebrzL0eGOQ7byhB6+BL9vG/HBLp4dbWRtC3neWbeebYXhl7ZN4 888cVLqjCBYWabiU7B6M5CumSkmtyoJsGQgvgipVliptvipu06nwqBMnXQtCyRNyiGKF 07KCbLAf9ZAxw5CCAxvcwf6kdLkZN0rrOv1KAOhKVpLnXl51KH5UYAbW4aU6gnG1A9km aHeQ== X-Gm-Message-State: AOAM531E10UYNN6zbpjvN9ns0wtwA+UNwcgQOavLBy6omp58YlLcdeh5 fo+ef1N/KjitpRKaUPeRHoHwbeillZE= X-Google-Smtp-Source: ABdhPJxKjU5TGZyKRdBnqn8qXn5aURpX9Dc8PKc1Dbx8eQhD2CxAEM3Mg+2KO1zU7kyVb8xBL5+hlw== X-Received: by 2002:a7b:cb45:: with SMTP id v5mr2052757wmj.2.1617734873255; Tue, 06 Apr 2021 11:47:53 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id o62sm5149497wmo.3.2021.04.06.11.47.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Apr 2021 11:47:52 -0700 (PDT) Message-Id: In-Reply-To: References: Date: Tue, 06 Apr 2021 18:47:47 +0000 Subject: [PATCH v2 2/5] test-lib: use exact match for test_subcommand Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: tom.saeger@oracle.com, gitster@pobox.com, sunshine@sunshineco.com, Derrick Stolee , Derrick Stolee , Derrick Stolee Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Derrick Stolee From: Derrick Stolee The use of 'grep' inside test_subcommand uses general patterns, leading to sometimes needing escape characters to avoid incorrect matches. Further, some platforms interpret regular expression metacharacters differently. Furthermore, it can be difficult to know which characters need escaping since the actual regular expression language implemented by various `grep`s differs between platforms; for instance, some may employ pure BRE, whereas others a mix of BRE & ERE. Sidestep this difficulty by using `grep -F` to use an exact match. This requires removing escape characters from existing callers. Luckily, this is only one test that expects refspecs as part of the subcommand. Helped-by: Eric Sunshine Signed-off-by: Derrick Stolee --- t/t7900-maintenance.sh | 4 ++-- t/test-lib-functions.sh | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/t/t7900-maintenance.sh b/t/t7900-maintenance.sh index 2412d8c5c006..37eed6ed3aa3 100755 --- a/t/t7900-maintenance.sh +++ b/t/t7900-maintenance.sh @@ -142,8 +142,8 @@ test_expect_success 'prefetch multiple remotes' ' test_commit -C clone2 two && GIT_TRACE2_EVENT="$(pwd)/run-prefetch.txt" git maintenance run --task=prefetch 2>/dev/null && fetchargs="--prune --no-tags --no-write-fetch-head --recurse-submodules=no --refmap= --quiet" && - test_subcommand git fetch remote1 $fetchargs +refs/heads/\\*:refs/prefetch/remote1/\\* X-Patchwork-Id: 12185721 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6C2FBC433B4 for ; Tue, 6 Apr 2021 18:48:00 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4CE77613C0 for ; Tue, 6 Apr 2021 18:48:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240705AbhDFSsH (ORCPT ); Tue, 6 Apr 2021 14:48:07 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43918 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240547AbhDFSsE (ORCPT ); Tue, 6 Apr 2021 14:48:04 -0400 Received: from mail-wm1-x330.google.com (mail-wm1-x330.google.com [IPv6:2a00:1450:4864:20::330]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 21EF5C06174A for ; Tue, 6 Apr 2021 11:47:55 -0700 (PDT) Received: by mail-wm1-x330.google.com with SMTP id d191so7851897wmd.2 for ; Tue, 06 Apr 2021 11:47:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=ieKN0ePML38Z+JEsF9arGpYtZ2tbULScvKE8Rh2Dso4=; b=e1T8TzHaZSS4DuJMbpP50gUWQ/NfEIeU0L92PsVkl+gF37sqxznexFnPrpTxE+rj0J UPofYcxaa86XOL55ZTGa8aAUvRVH2noO3yi7Q1qABSdXpzNFzY9aLb3DuNVwOQnoGRuh 4U68LWLv0Jz3fnOGUP9874VLsIhpS38DpLRi5AC9vrS2p7DH2bdTwIip2WZtCGS+fidA n3JRipNIseL8bfv3qWOr6wczRQ/Bg2wrhl54jLr54jiKXVCiZPcUux+rmkuOzs5kWzNO 6SOxDP55Kk6QIhw+dQKWRGslJDTF//h+1TvYxyM4N+D/Ef1M21vPHf48xypE8W/BIbnj B54g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=ieKN0ePML38Z+JEsF9arGpYtZ2tbULScvKE8Rh2Dso4=; b=t5XxmQrK+pbSqzMa8YKGeSNYL/nkEOrwQPKNRKB4wD/GSJLCYbQBfolzefdV2IhfrM A6pXGmagNC22A754bWGvI98CP8KnxWm34TEjv2kqF8fSdvsNAg56dsW/mG34nH7ObeS5 ZoPB8YQrkbtwjJzrN+hsJ3XrFABS1E6RpGBqtZ7GsK5BcKTKi7DAbP7soG3W2BC81GyV +l+rEIMVypdMPMgxCRDJvDtYX1qXyd2n4yS82LZiLFrt0yH6ZQ0zH3+pcYXLt0vNht9v Zx12wALgW0AvH3J/KNzFZWSJbbIX3Rkk+PMjgtlDz+kKYbgr4PdF5v8VI6Ckfr/1UsPK rJ7w== X-Gm-Message-State: AOAM533tMfjuFKbvpD3/pyldjVp9ZMIkmccjbWeWWmt4WBKnU3u1ASBr 242o1zB2AbOiwzjNzG5rUBtNek88KgA= X-Google-Smtp-Source: ABdhPJxsgim0ysaIm4+bB90ldGzN9VocwFWnS+rBvaJHOuxeECJCeOZ/7GJzcb1GNyXS+QVWK5DhAw== X-Received: by 2002:a1c:e906:: with SMTP id q6mr5396362wmc.138.1617734873890; Tue, 06 Apr 2021 11:47:53 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id r11sm18592964wrp.70.2021.04.06.11.47.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Apr 2021 11:47:53 -0700 (PDT) Message-Id: <96388d949b98668d1f272090f7100da09a1c977d.1617734870.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Tue, 06 Apr 2021 18:47:48 +0000 Subject: [PATCH v2 3/5] refspec: output a refspec item Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: tom.saeger@oracle.com, gitster@pobox.com, sunshine@sunshineco.com, Derrick Stolee , Derrick Stolee , Derrick Stolee Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Derrick Stolee From: Derrick Stolee Add a new method, refspec_item_format(), that takes a 'struct refspec_item' pointer as input and returns a string for how that refspec item should be written to Git's config or a subcommand, such as 'git fetch'. There are several subtleties regarding special-case refspecs that can occur and are represented in t5511-refspec.sh. These cases will be explored in new tests in the following change. It requires adding a new test helper in order to test this format directly, so that is saved for a separate change to keep this one focused on the logic of the format method. A future change will consume this method when translating refspecs in the 'prefetch' task of the 'git maintenance' builtin. Signed-off-by: Derrick Stolee --- refspec.c | 23 +++++++++++++++++++++++ refspec.h | 2 ++ 2 files changed, 25 insertions(+) diff --git a/refspec.c b/refspec.c index e3d852c0bfec..e79cde3c58be 100644 --- a/refspec.c +++ b/refspec.c @@ -180,6 +180,29 @@ void refspec_item_clear(struct refspec_item *item) item->exact_sha1 = 0; } +char *refspec_item_format(const struct refspec_item *rsi) +{ + struct strbuf buf = STRBUF_INIT; + + if (rsi->matching) + return xstrdup(":"); + + if (rsi->negative) + strbuf_addch(&buf, '^'); + else if (rsi->force) + strbuf_addch(&buf, '+'); + + if (rsi->src) + strbuf_addstr(&buf, rsi->src); + + if (rsi->dst) { + strbuf_addch(&buf, ':'); + strbuf_addstr(&buf, rsi->dst); + } + + return strbuf_detach(&buf, NULL); +} + void refspec_init(struct refspec *rs, int fetch) { memset(rs, 0, sizeof(*rs)); diff --git a/refspec.h b/refspec.h index 8b79891d3218..9f2ddc7949a1 100644 --- a/refspec.h +++ b/refspec.h @@ -56,6 +56,8 @@ int refspec_item_init(struct refspec_item *item, const char *refspec, void refspec_item_init_or_die(struct refspec_item *item, const char *refspec, int fetch); void refspec_item_clear(struct refspec_item *item); +char *refspec_item_format(const struct refspec_item *rsi); + void refspec_init(struct refspec *rs, int fetch); void refspec_append(struct refspec *rs, const char *refspec); __attribute__((format (printf,2,3))) From patchwork Tue Apr 6 18:47:49 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Derrick Stolee X-Patchwork-Id: 12185717 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C94BCC43461 for ; Tue, 6 Apr 2021 18:47:57 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8B188613C4 for ; Tue, 6 Apr 2021 18:47:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240567AbhDFSsE (ORCPT ); Tue, 6 Apr 2021 14:48:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43926 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240251AbhDFSsE (ORCPT ); Tue, 6 Apr 2021 14:48:04 -0400 Received: from mail-wm1-x32c.google.com (mail-wm1-x32c.google.com [IPv6:2a00:1450:4864:20::32c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D854DC06175F for ; Tue, 6 Apr 2021 11:47:55 -0700 (PDT) Received: by mail-wm1-x32c.google.com with SMTP id w203-20020a1c49d40000b029010c706d0642so1537409wma.0 for ; Tue, 06 Apr 2021 11:47:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=bG1nSp9rfJSVvBqkxvkScxaw7IeJkTmHeRV7jpB+hNs=; b=D0HMeO4Px56RQJK0vj4Oj3LWstIn5OnNmmaHVQXe4ScybtCSkLf3DrXTu7stj8BHMy N542KC7JE8GyNvNlwIChqqjZGi9/iYgsaMCbMf2ZdIIucO2IqNuMOtLPG2pnUWWHvf9g bVeyx1PHtBAkvE7W1k1o+UeALni3+1uGO7jrcu0NHMj8LRWE5oOyRBgT2nAkq7ir2WD5 Y774zlA5ZpUdCk0QwMKDrfVTtjK6yoUfcDgWKxH5kq5VBTloFlUj/6ANEonyIfj2JcSN bXdUsGUZEDS57HuJJ3ekh1mKy+0V7jMRkYmuI1upharl78Ht0x1xwaLA1bGE0Vgr0imW fQBw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=bG1nSp9rfJSVvBqkxvkScxaw7IeJkTmHeRV7jpB+hNs=; b=RocfV5GiBoh4d8QZB6OW3we/GaXMqWvYAm3wVC1HDCnxUusk9950lC8yNgmJz0nesp GQPzZWu6SqpS2Zo/YBV2O15s2Z60RYzaPn+bQhaOZMAI88kfv3S31/SHunx9r9lG+lhf x3DU1LKC7sXIkAUwoX58fqjMFhJNo+4/JgQb6lL53DkySKs4dnefczHBF3PHt9XuBjRW fXHj26wl5xjkQkwIcsh4R+BIRpDKvvlxoosC4EnYPe1w1R5kTFjbenkLRsol1p6/JJXr lfcXSLsnieCkZw3ivKeBII0lgWNvPMhe7OJmYOuoY8LL6WtQshKa6Y2ORpgvvAbwlVGU 1ORQ== X-Gm-Message-State: AOAM532EodeHHRAMkwYzUD2FXj6QKh08VNOgN/ZgCLLIvm0Lb3UZelBC lnMz8uHckbILiDVYCBrZnNMuRo6zqEI= X-Google-Smtp-Source: ABdhPJzWwW2O/33iJixBZ0VHaacb54sN9n0qI1JWoYDBh7rJop7ER19ItcqgUKob+3RsUSKg/3ISBg== X-Received: by 2002:a05:600c:3796:: with SMTP id o22mr5359783wmr.139.1617734874656; Tue, 06 Apr 2021 11:47:54 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id l6sm32895235wrt.56.2021.04.06.11.47.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Apr 2021 11:47:54 -0700 (PDT) Message-Id: In-Reply-To: References: Date: Tue, 06 Apr 2021 18:47:49 +0000 Subject: [PATCH v2 4/5] test-tool: test refspec input/output Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: tom.saeger@oracle.com, gitster@pobox.com, sunshine@sunshineco.com, Derrick Stolee , Derrick Stolee , Derrick Stolee Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Derrick Stolee From: Derrick Stolee Add a new test-helper, 'test-tool refspec', that currently reads stdin line-by-line and translates the refspecs using the parsing logic of refspec_item_init() and writes them to output. Create a test in t5511-refspec.sh that uses this helper to test several known special cases. This includes all of the special properties of the 'struct refspec_item', including: * force: The refspec starts with '+'. * pattern: Each side of the refspec has a glob character ('*') * matching: The refspec is simply the string ":". * exact_sha1: The 'src' string is a 40-character hex string. * negative: The refspec starts with '^' and 'dst' is NULL. While the exact_sha1 property doesn't require special logic in refspec_item_format, it is still tested here for completeness. There is also the special-case refspec "@" which translates to "HEAD". Note that if a refspec does not start with "refs/", then that is not incorporated as part of the 'struct refspec_item'. This behavior is confirmed by these tests. These refspecs still work in the wild because the refs layer interprets them appropriately as branches, prepending "refs/" or "refs/heads/" as necessary. I spent some time attempting to insert these prefixes explicitly in parse_refspec(), but these are several subtleties I was unable to overcome. If such a change were to be made, then this new test in t5511-refspec.sh will need to be updated with new output. For example, the input lines ending with "translated" are designed to demonstrate these subtleties. Signed-off-by: Derrick Stolee --- Makefile | 1 + t/helper/test-refspec.c | 44 +++++++++++++++++++++++++++++++++++++++++ t/helper/test-tool.c | 1 + t/helper/test-tool.h | 1 + t/t5511-refspec.sh | 41 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 88 insertions(+) create mode 100644 t/helper/test-refspec.c diff --git a/Makefile b/Makefile index a6a73c574191..f858c9f25976 100644 --- a/Makefile +++ b/Makefile @@ -734,6 +734,7 @@ TEST_BUILTINS_OBJS += test-reach.o TEST_BUILTINS_OBJS += test-read-cache.o TEST_BUILTINS_OBJS += test-read-graph.o TEST_BUILTINS_OBJS += test-read-midx.o +TEST_BUILTINS_OBJS += test-refspec.o TEST_BUILTINS_OBJS += test-ref-store.o TEST_BUILTINS_OBJS += test-regex.o TEST_BUILTINS_OBJS += test-repository.o diff --git a/t/helper/test-refspec.c b/t/helper/test-refspec.c new file mode 100644 index 000000000000..b06735ded208 --- /dev/null +++ b/t/helper/test-refspec.c @@ -0,0 +1,44 @@ +#include "cache.h" +#include "parse-options.h" +#include "refspec.h" +#include "strbuf.h" +#include "test-tool.h" + +static const char * const refspec_usage[] = { + N_("test-tool refspec [--fetch]"), + NULL +}; + +int cmd__refspec(int argc, const char **argv) +{ + struct strbuf line = STRBUF_INIT; + int fetch = 0; + + struct option refspec_options [] = { + OPT_BOOL(0, "fetch", &fetch, + N_("enable the 'fetch' option for parsing refpecs")), + OPT_END() + }; + + argc = parse_options(argc, argv, NULL, refspec_options, + refspec_usage, 0); + + while (strbuf_getline(&line, stdin) != EOF) { + struct refspec_item rsi; + char *buf; + + if (!refspec_item_init(&rsi, line.buf, fetch)) { + printf("failed to parse %s\n", line.buf); + continue; + } + + buf = refspec_item_format(&rsi); + printf("%s\n", buf); + free(buf); + + refspec_item_clear(&rsi); + } + + strbuf_release(&line); + return 0; +} diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c index 287aa6002307..f534ad1731a9 100644 --- a/t/helper/test-tool.c +++ b/t/helper/test-tool.c @@ -55,6 +55,7 @@ static struct test_cmd cmds[] = { { "read-cache", cmd__read_cache }, { "read-graph", cmd__read_graph }, { "read-midx", cmd__read_midx }, + { "refspec", cmd__refspec }, { "ref-store", cmd__ref_store }, { "regex", cmd__regex }, { "repository", cmd__repository }, diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h index 9ea4b31011dd..46a0b8850f17 100644 --- a/t/helper/test-tool.h +++ b/t/helper/test-tool.h @@ -44,6 +44,7 @@ int cmd__reach(int argc, const char **argv); int cmd__read_cache(int argc, const char **argv); int cmd__read_graph(int argc, const char **argv); int cmd__read_midx(int argc, const char **argv); +int cmd__refspec(int argc, const char **argv); int cmd__ref_store(int argc, const char **argv); int cmd__regex(int argc, const char **argv); int cmd__repository(int argc, const char **argv); diff --git a/t/t5511-refspec.sh b/t/t5511-refspec.sh index be025b90f989..489bec08d570 100755 --- a/t/t5511-refspec.sh +++ b/t/t5511-refspec.sh @@ -93,4 +93,45 @@ test_refspec fetch "refs/heads/${good}" bad=$(printf '\011tab') test_refspec fetch "refs/heads/${bad}" invalid +test_expect_success 'test input/output round trip' ' + cat >input <<-\EOF && + +refs/heads/*:refs/remotes/origin/* + refs/heads/*:refs/remotes/origin/* + refs/heads/main:refs/remotes/frotz/xyzzy + :refs/remotes/frotz/deleteme + ^refs/heads/secrets + refs/heads/secret:refs/heads/translated + refs/heads/secret:heads/translated + refs/heads/secret:remotes/translated + secret:translated + refs/heads/*:remotes/xxy/* + refs/heads*/for-linus:refs/remotes/mine/* + 2e36527f23b7f6ae15e6f21ac3b08bf3fed6ee48:refs/heads/fixed + HEAD + @ + : + EOF + cat >expect <<-\EOF && + +refs/heads/*:refs/remotes/origin/* + refs/heads/*:refs/remotes/origin/* + refs/heads/main:refs/remotes/frotz/xyzzy + :refs/remotes/frotz/deleteme + ^refs/heads/secrets + refs/heads/secret:refs/heads/translated + refs/heads/secret:heads/translated + refs/heads/secret:remotes/translated + secret:translated + refs/heads/*:remotes/xxy/* + refs/heads*/for-linus:refs/remotes/mine/* + 2e36527f23b7f6ae15e6f21ac3b08bf3fed6ee48:refs/heads/fixed + HEAD + HEAD + : + EOF + test-tool refspec output && + test_cmp expect output && + test-tool refspec --fetch output && + test_cmp expect output +' + test_done From patchwork Tue Apr 6 18:47:50 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Derrick Stolee X-Patchwork-Id: 12185723 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 60020C433ED for ; Tue, 6 Apr 2021 18:48:02 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3216E600D4 for ; Tue, 6 Apr 2021 18:48:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240679AbhDFSsJ (ORCPT ); Tue, 6 Apr 2021 14:48:09 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43926 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240728AbhDFSsI (ORCPT ); Tue, 6 Apr 2021 14:48:08 -0400 Received: from mail-wm1-x332.google.com (mail-wm1-x332.google.com [IPv6:2a00:1450:4864:20::332]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 874B1C061760 for ; Tue, 6 Apr 2021 11:47:56 -0700 (PDT) Received: by mail-wm1-x332.google.com with SMTP id g18-20020a7bc4d20000b0290116042cfdd8so4701280wmk.4 for ; Tue, 06 Apr 2021 11:47:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=message-id:in-reply-to:references:from:date:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=kvY5G+SapFzP5WhQpiuvL0EY93uTcLFi8N2kpBfVTFg=; b=oqJV20bQ0DNRFcGpUNlWTgdlX4jpkwSZfJE4X4nVO+WDt69tY4xaE1AKlmgG+2o38T KbjotQ5OxGFnlxmNj+0c76rirAfz6LiQhFwx1bK17xyIQbHZ/HLjSyM4+x8R/nhiwmzk rZxf5PJEjDnWeCd3+M+O7M0UiokDmOFzWkfgejrnbPi7CGhmZXvcrvwQYUtZ6667D4AH CUb4u0UrN0jSzGhTU94TyFA868MvW4WBrgO/+woHueddzuNvUSqkVYghFaLy6AH4x9ij KvSXtBstPP/5e18Oi5d0mx/j7mNbTiT4f1hbo1MjOn/1g03Qev4lCjDyHwsVUj0UCMSI 6iEA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:message-id:in-reply-to:references:from:date :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=kvY5G+SapFzP5WhQpiuvL0EY93uTcLFi8N2kpBfVTFg=; b=GSe0+O9C3G3SkWlMiXoXrywuIU9ash1ks0Lbzmxa7CGNI4YuBI5JJdlhXm2VyTQDYo dsYna9nxXWDsWZi2vGHUi0KNEkaLaVbhIkkkqae5zXskjFyAT7hjBOCqlnQ706xG4K4S B8HZqjL5PSBFVakJka4eCl1/qaQqwk8EnjUow2WRf1muutQflxFv9yYIM9eCNBfxmSMv GKIAtRMWxabA0606z1pKtONF8zE5w9MAlCZ0OZ9o4XUqWnsYqYWPJthGtAhGRreZDMJ6 VBm3Ku7N+8ZzA/3M5ZFoVfN2l3/tuDB5c8l2vxjPgEhEnoDc6EE/YpwPTAETsqrNUAT7 cdeQ== X-Gm-Message-State: AOAM533urqqbOXy0nwEtboQQclU2cG5LeewE6tTuLVC659r7Wk+Hs2B/ 5TWxoNuPmqmevbwgszxHRRg1r629J4g= X-Google-Smtp-Source: ABdhPJxwgpVUjw3zsJDTG7Z2FQMytpU6X0xXlg9eDFwDx1n2sb75xxurqk8Kc1AjiBpT28yAf2/CmQ== X-Received: by 2002:a05:600c:4f8e:: with SMTP id n14mr5485450wmq.34.1617734875248; Tue, 06 Apr 2021 11:47:55 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id s5sm18148530wrw.2.2021.04.06.11.47.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Apr 2021 11:47:54 -0700 (PDT) Message-Id: <9592224e3d428762c6f9b38a0bcc2cee5c3dff6c.1617734871.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Tue, 06 Apr 2021 18:47:50 +0000 Subject: [PATCH v2 5/5] maintenance: allow custom refspecs during prefetch Fcc: Sent MIME-Version: 1.0 To: git@vger.kernel.org Cc: tom.saeger@oracle.com, gitster@pobox.com, sunshine@sunshineco.com, Derrick Stolee , Derrick Stolee , Derrick Stolee Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Derrick Stolee From: Derrick Stolee The prefetch task previously used the default refspec source plus a custom refspec destination to avoid colliding with remote refs: +refs/heads/*:refs/prefetch//* However, some users customize their refspec to reduce how much data they download from specific remotes. This can involve restrictive patterns for fetching or negative patterns to avoid downloading some refs. Modify fetch_remote() to iterate over the remote's refspec list and translate that into the appropriate prefetch scenario. Specifically, re-parse the raw form of the refspec into a new 'struct refspec' and modify the 'dst' member to replace a leading "refs/" substring with "refs/prefetch/", or prepend "refs/prefetch/" to 'dst' otherwise. Negative refspecs do not have a 'dst' so they can be transferred to the 'git fetch' command unmodified. This prefix change provides the benefit of keeping whatever collisions may exist in the custom refspecs, if that is a desirable outcome. This changes the names of the refs that would be fetched by the default refspec. Instead of "refs/prefetch//" they will now go to "refs/prefetch/remotes//". While this is a change, it is not a seriously breaking one: these refs are intended to be hidden and not used. Update the documentation to be more generic about the destination refs. Do not mention custom refpecs explicitly, as that does not need to be highlighted in this documentation. The important part of placing refs in refs/prefetch remains. Reported-by: Tom Saeger Signed-off-by: Derrick Stolee --- Documentation/git-maintenance.txt | 3 +-- builtin/gc.c | 37 +++++++++++++++++++++++++- t/t7900-maintenance.sh | 43 ++++++++++++++++++++++++++----- 3 files changed, 74 insertions(+), 9 deletions(-) diff --git a/Documentation/git-maintenance.txt b/Documentation/git-maintenance.txt index 80ddd33ceba0..95a24264eb10 100644 --- a/Documentation/git-maintenance.txt +++ b/Documentation/git-maintenance.txt @@ -94,8 +94,7 @@ prefetch:: objects from all registered remotes. For each remote, a `git fetch` command is run. The refmap is custom to avoid updating local or remote branches (those in `refs/heads` or `refs/remotes`). Instead, the - remote refs are stored in `refs/prefetch//`. Also, tags are - not updated. + refs are stored in `refs/prefetch/`. Also, tags are not updated. + This is done to avoid disrupting the remote-tracking branches. The end users expect these refs to stay unmoved unless they initiate a fetch. With prefetch diff --git a/builtin/gc.c b/builtin/gc.c index fa8128de9ae1..76f347dd6b11 100644 --- a/builtin/gc.c +++ b/builtin/gc.c @@ -32,6 +32,7 @@ #include "remote.h" #include "object-store.h" #include "exec-cmd.h" +#include "refspec.h" #define FAILED_RUN "failed to run %s" @@ -877,6 +878,7 @@ static int fetch_remote(struct remote *remote, void *cbdata) { struct maintenance_run_opts *opts = cbdata; struct child_process child = CHILD_PROCESS_INIT; + int i; child.git_cmd = 1; strvec_pushl(&child.args, "fetch", remote->name, "--prune", "--no-tags", @@ -886,7 +888,40 @@ static int fetch_remote(struct remote *remote, void *cbdata) if (opts->quiet) strvec_push(&child.args, "--quiet"); - strvec_pushf(&child.args, "+refs/heads/*:refs/prefetch/%s/*", remote->name); + for (i = 0; i < remote->fetch.nr; i++) { + struct refspec_item replace; + struct refspec_item *rsi = &remote->fetch.items[i]; + struct strbuf new_dst = STRBUF_INIT; + size_t ignore_len = 0; + char *replace_string; + + if (rsi->negative) { + strvec_push(&child.args, remote->fetch.raw[i]); + continue; + } + + refspec_item_init(&replace, remote->fetch.raw[i], 1); + + /* + * If a refspec dst starts with "refs/" at the start, + * then we will replace "refs/" with "refs/prefetch/". + * Otherwise, we will prepend the dst string with + * "refs/prefetch/". + */ + if (!strncmp(replace.dst, "refs/", 5)) + ignore_len = 5; + + strbuf_addstr(&new_dst, "refs/prefetch/"); + strbuf_addstr(&new_dst, replace.dst + ignore_len); + free(replace.dst); + replace.dst = strbuf_detach(&new_dst, NULL); + + replace_string = refspec_item_format(&replace); + strvec_push(&child.args, replace_string); + free(replace_string); + + refspec_item_clear(&replace); + } return !!run_command(&child); } diff --git a/t/t7900-maintenance.sh b/t/t7900-maintenance.sh index 37eed6ed3aa3..03487be3af38 100755 --- a/t/t7900-maintenance.sh +++ b/t/t7900-maintenance.sh @@ -142,20 +142,51 @@ test_expect_success 'prefetch multiple remotes' ' test_commit -C clone2 two && GIT_TRACE2_EVENT="$(pwd)/run-prefetch.txt" git maintenance run --task=prefetch 2>/dev/null && fetchargs="--prune --no-tags --no-write-fetch-head --recurse-submodules=no --refmap= --quiet" && - test_subcommand git fetch remote1 $fetchargs "+refs/heads/*:refs/prefetch/remote1/*" log && ! grep "prefetch" log ' +test_expect_success 'prefetch custom refspecs' ' + git -C clone1 branch -f special/fetched HEAD && + git -C clone1 branch -f special/secret/not-fetched HEAD && + + # create multiple refspecs for remote1 + git config --add remote.remote1.fetch "+refs/heads/special/fetched:refs/heads/fetched" && + git config --add remote.remote1.fetch "^refs/heads/special/secret/not-fetched" && + + GIT_TRACE2_EVENT="$(pwd)/prefetch-refspec.txt" git maintenance run --task=prefetch 2>/dev/null && + + fetchargs="--prune --no-tags --no-write-fetch-head --recurse-submodules=no --refmap= --quiet" && + + # skips second refspec because it is not a pattern type + rs1="+refs/heads/*:refs/prefetch/remotes/remote1/*" && + rs2="+refs/heads/special/fetched:refs/prefetch/heads/fetched" && + rs3="^refs/heads/special/secret/not-fetched" && + + test_subcommand git fetch remote1 $fetchargs "$rs1" "$rs2" "$rs3"