From patchwork Tue Nov 14 19:53:49 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victoria Dye X-Patchwork-Id: 13455821 Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0382026ADF for ; Tue, 14 Nov 2023 19:54:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="ZSRHq8yl" Received: from mail-qk1-x72a.google.com (mail-qk1-x72a.google.com [IPv6:2607:f8b0:4864:20::72a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A76A3114 for ; Tue, 14 Nov 2023 11:54:04 -0800 (PST) Received: by mail-qk1-x72a.google.com with SMTP id af79cd13be357-778925998cbso399338585a.0 for ; Tue, 14 Nov 2023 11:54:04 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1699991643; x=1700596443; darn=vger.kernel.org; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:from:to:cc:subject:date :message-id:reply-to; bh=pzViII5dMOLWDmCjCcUV7YWruXOQN2wnQL9UcYEfTl4=; b=ZSRHq8ylH+E5X7tAe/ABBR4nYOl+WsxKCAbXpWN9hG++61UGQQNRYJ0K1dxl77+GUD 8KZQuzaZpdl06IuxDzVyWR3F1n5YruzE4ahaY2fvnGOQ07x+zvza2jc4QK9bPUp3o3lb Q+x9UE6VXlaV80AxPohCgv/etiGJ9mNCew17oI5d8zqRtPa3QbgfBRj4plc4EXnVkP9C Hec3x1ZS9kHiWFHtDaKlEvVk2uGiVKvVIMsJAmc8ncRsyf+tOtYT3GPLFga/nzq0gb8P 1q1tzwuFyFLD8oF3yk6DZE+Wqcz4Q2y9sKK1DsH2B5+4FbaYdJEGdxmUAx5Ki02Jn00V ETfA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1699991643; x=1700596443; 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 :subject:date:message-id:reply-to; bh=pzViII5dMOLWDmCjCcUV7YWruXOQN2wnQL9UcYEfTl4=; b=RfBMPlTfGpXLfM1sf0RMiWPEBORKu2jgSL0qyfC9Gb5QJWN4xf7BjtsNJC6VzNA2e6 9Hzurs76CkswyC43ogJS+ZDz3LOIbvsfRzli2IcgZe6RRG69fQaDiSg0myvX0rfLkPsU jzOuPmcCJ0LG8NjwN+xJ4uR0nvnuzC+prLLe8CmsjI447kUdhJM8hDhckqnsoxQWzxNy 2nLjRuoMuXkMYCHl4i+PQpHz0wuwRJegAAnbx6gE2lCyS4CAngZH/x9CBxSW27w9NQE3 Khr/9KgZ4bt9ZANyn4HTO1wPAWdMcOQd6U5mVSCgOhX3aQsWSTKRPBNgdWvhBvRMxHQW ATdg== X-Gm-Message-State: AOJu0Yx+mSg9ARgW+jtokDRcA6yiNAGC1pDcbfFv0axT4A7rYxs/rdr3 F/qRK9388VBQMrMe14NfwxqOMZJnBRY= X-Google-Smtp-Source: AGHT+IGZOvM3phxwIABI4kkrtNzUlB+L+ZrZPM/Dk+sKn205SY8oEjBGL/0nbunz9ypr/vLqdZSvhw== X-Received: by 2002:a05:620a:6505:b0:778:8ce5:f657 with SMTP id qb5-20020a05620a650500b007788ce5f657mr3821520qkn.20.1699991643372; Tue, 14 Nov 2023 11:54:03 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id u24-20020ae9c018000000b0077589913a8bsm2874994qkk.132.2023.11.14.11.54.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 14 Nov 2023 11:54:03 -0800 (PST) Message-ID: <074da1ff3e85927324c42a3fa65e4239f051cd70.1699991638.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Tue, 14 Nov 2023 19:53:49 +0000 Subject: [PATCH v2 01/10] ref-filter.c: really don't sort when using --no-sort Fcc: Sent Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 To: git@vger.kernel.org Cc: Patrick Steinhardt , =?utf-8?q?=C3=98ystein?= Walle , Kristoffer Haugsbakk , Victoria Dye , Victoria Dye From: Victoria Dye From: Victoria Dye When '--no-sort' is passed to 'for-each-ref', 'tag', and 'branch', the printed refs are still sorted by ascending refname. Change the handling of sort options in these commands so that '--no-sort' to truly disables sorting. '--no-sort' does not disable sorting in these commands is because their option parsing does not distinguish between "the absence of '--sort'" (and/or values for tag.sort & branch.sort) and '--no-sort'. Both result in an empty 'sorting_options' string list, which is parsed by 'ref_sorting_options()' to create the 'struct ref_sorting *' for the command. If the string list is empty, 'ref_sorting_options()' interprets that as "the absence of '--sort'" and returns the default ref sorting structure (equivalent to "refname" sort). To handle '--no-sort' properly while preserving the "refname" sort in the "absence of --sort'" case, first explicitly add "refname" to the string list *before* parsing options. This alone doesn't actually change any behavior, since 'compare_refs()' already falls back on comparing refnames if two refs are equal w.r.t all other sort keys. Now that the string list is populated by default, '--no-sort' is the only way to empty the 'sorting_options' string list. Update 'ref_sorting_options()' to return a NULL 'struct ref_sorting *' if the string list is empty, and add a condition to 'ref_array_sort()' to skip the sort altogether if the sort structure is NULL. Note that other functions using 'struct ref_sorting *' do not need any changes because they already ignore NULL values. Finally, remove the condition around sorting in 'ls-remote', since it's no longer necessary. Unlike 'for-each-ref' et. al., it does *not* do any sorting by default. This default is preserved by simply leaving its sort key string list empty before parsing options; if no additional sort keys are set, 'struct ref_sorting *' is NULL and sorting is skipped. Signed-off-by: Victoria Dye --- builtin/branch.c | 6 ++++ builtin/for-each-ref.c | 3 ++ builtin/ls-remote.c | 11 +++---- builtin/tag.c | 6 ++++ ref-filter.c | 19 ++---------- t/t3200-branch.sh | 68 +++++++++++++++++++++++++++++++++++++++-- t/t6300-for-each-ref.sh | 21 +++++++++++++ t/t7004-tag.sh | 45 +++++++++++++++++++++++++++ 8 files changed, 153 insertions(+), 26 deletions(-) diff --git a/builtin/branch.c b/builtin/branch.c index e7ee9bd0f15..d67738bbcaa 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -767,7 +767,13 @@ int cmd_branch(int argc, const char **argv, const char *prefix) if (argc == 2 && !strcmp(argv[1], "-h")) usage_with_options(builtin_branch_usage, options); + /* + * Try to set sort keys from config. If config does not set any, + * fall back on default (refname) sorting. + */ git_config(git_branch_config, &sorting_options); + if (!sorting_options.nr) + string_list_append(&sorting_options, "refname"); track = git_branch_track; diff --git a/builtin/for-each-ref.c b/builtin/for-each-ref.c index 350bfa6e811..93b370f550b 100644 --- a/builtin/for-each-ref.c +++ b/builtin/for-each-ref.c @@ -67,6 +67,9 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix) git_config(git_default_config, NULL); + /* Set default (refname) sorting */ + string_list_append(&sorting_options, "refname"); + parse_options(argc, argv, prefix, opts, for_each_ref_usage, 0); if (maxcount < 0) { error("invalid --count argument: `%d'", maxcount); diff --git a/builtin/ls-remote.c b/builtin/ls-remote.c index fc765754305..b416602b4d3 100644 --- a/builtin/ls-remote.c +++ b/builtin/ls-remote.c @@ -58,6 +58,7 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix) struct transport *transport; const struct ref *ref; struct ref_array ref_array; + struct ref_sorting *sorting; struct string_list sorting_options = STRING_LIST_INIT_DUP; struct option options[] = { @@ -141,13 +142,8 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix) item->symref = xstrdup_or_null(ref->symref); } - if (sorting_options.nr) { - struct ref_sorting *sorting; - - sorting = ref_sorting_options(&sorting_options); - ref_array_sort(sorting, &ref_array); - ref_sorting_release(sorting); - } + sorting = ref_sorting_options(&sorting_options); + ref_array_sort(sorting, &ref_array); for (i = 0; i < ref_array.nr; i++) { const struct ref_array_item *ref = ref_array.items[i]; @@ -157,6 +153,7 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix) status = 0; /* we found something */ } + ref_sorting_release(sorting); ref_array_clear(&ref_array); if (transport_disconnect(transport)) status = 1; diff --git a/builtin/tag.c b/builtin/tag.c index 3918eacbb57..64f3196cd4c 100644 --- a/builtin/tag.c +++ b/builtin/tag.c @@ -501,7 +501,13 @@ int cmd_tag(int argc, const char **argv, const char *prefix) setup_ref_filter_porcelain_msg(); + /* + * Try to set sort keys from config. If config does not set any, + * fall back on default (refname) sorting. + */ git_config(git_tag_config, &sorting_options); + if (!sorting_options.nr) + string_list_append(&sorting_options, "refname"); memset(&opt, 0, sizeof(opt)); filter.lines = -1; diff --git a/ref-filter.c b/ref-filter.c index e4d3510e28e..7250089b7c6 100644 --- a/ref-filter.c +++ b/ref-filter.c @@ -3142,7 +3142,8 @@ void ref_sorting_set_sort_flags_all(struct ref_sorting *sorting, void ref_array_sort(struct ref_sorting *sorting, struct ref_array *array) { - QSORT_S(array->items, array->nr, compare_refs, sorting); + if (sorting) + QSORT_S(array->items, array->nr, compare_refs, sorting); } static void append_literal(const char *cp, const char *ep, struct ref_formatting_state *state) @@ -3248,18 +3249,6 @@ static int parse_sorting_atom(const char *atom) return res; } -/* If no sorting option is given, use refname to sort as default */ -static struct ref_sorting *ref_default_sorting(void) -{ - static const char cstr_name[] = "refname"; - - struct ref_sorting *sorting = xcalloc(1, sizeof(*sorting)); - - sorting->next = NULL; - sorting->atom = parse_sorting_atom(cstr_name); - return sorting; -} - static void parse_ref_sorting(struct ref_sorting **sorting_tail, const char *arg) { struct ref_sorting *s; @@ -3283,9 +3272,7 @@ struct ref_sorting *ref_sorting_options(struct string_list *options) struct string_list_item *item; struct ref_sorting *sorting = NULL, **tail = &sorting; - if (!options->nr) { - sorting = ref_default_sorting(); - } else { + if (options->nr) { for_each_string_list_item(item, options) parse_ref_sorting(tail, item->string); } diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh index 3182abde27f..9918ba05dec 100755 --- a/t/t3200-branch.sh +++ b/t/t3200-branch.sh @@ -1570,9 +1570,10 @@ test_expect_success 'tracking with unexpected .fetch refspec' ' test_expect_success 'configured committerdate sort' ' git init -b main sort && + test_config -C sort branch.sort "committerdate" && + ( cd sort && - git config branch.sort committerdate && test_commit initial && git checkout -b a && test_commit a && @@ -1592,9 +1593,10 @@ test_expect_success 'configured committerdate sort' ' ' test_expect_success 'option override configured sort' ' + test_config -C sort branch.sort "committerdate" && + ( cd sort && - git config branch.sort committerdate && git branch --sort=refname >actual && cat >expect <<-\EOF && a @@ -1606,10 +1608,70 @@ test_expect_success 'option override configured sort' ' ) ' +test_expect_success '--no-sort cancels config sort keys' ' + test_config -C sort branch.sort "-refname" && + + ( + cd sort && + + # objecttype is identical for all of them, so sort falls back on + # default (ascending refname) + git branch \ + --no-sort \ + --sort="objecttype" >actual && + cat >expect <<-\EOF && + a + * b + c + main + EOF + test_cmp expect actual + ) + +' + +test_expect_success '--no-sort cancels command line sort keys' ' + ( + cd sort && + + # objecttype is identical for all of them, so sort falls back on + # default (ascending refname) + git branch \ + --sort="-refname" \ + --no-sort \ + --sort="objecttype" >actual && + cat >expect <<-\EOF && + a + * b + c + main + EOF + test_cmp expect actual + ) +' + +test_expect_success '--no-sort without subsequent --sort prints expected branches' ' + ( + cd sort && + + # Sort the results with `sort` for a consistent comparison + # against expected + git branch --no-sort | sort >actual && + cat >expect <<-\EOF && + a + c + main + * b + EOF + test_cmp expect actual + ) +' + test_expect_success 'invalid sort parameter in configuration' ' + test_config -C sort branch.sort "v:notvalid" && + ( cd sort && - git config branch.sort "v:notvalid" && # this works in the "listing" mode, so bad sort key # is a dying offence. diff --git a/t/t6300-for-each-ref.sh b/t/t6300-for-each-ref.sh index 00a060df0b5..0613e5e3623 100755 --- a/t/t6300-for-each-ref.sh +++ b/t/t6300-for-each-ref.sh @@ -1335,6 +1335,27 @@ test_expect_success '--no-sort cancels the previous sort keys' ' test_cmp expected actual ' +test_expect_success '--no-sort without subsequent --sort prints expected refs' ' + cat >expected <<-\EOF && + refs/tags/multi-ref1-100000-user1 + refs/tags/multi-ref1-100000-user2 + refs/tags/multi-ref1-200000-user1 + refs/tags/multi-ref1-200000-user2 + refs/tags/multi-ref2-100000-user1 + refs/tags/multi-ref2-100000-user2 + refs/tags/multi-ref2-200000-user1 + refs/tags/multi-ref2-200000-user2 + EOF + + # Sort the results with `sort` for a consistent comparison against + # expected + git for-each-ref \ + --format="%(refname)" \ + --no-sort \ + "refs/tags/multi-*" | sort >actual && + test_cmp expected actual +' + test_expect_success 'do not dereference NULL upon %(HEAD) on unborn branch' ' test_when_finished "git checkout main" && git for-each-ref --format="%(HEAD) %(refname:short)" refs/heads/ >actual && diff --git a/t/t7004-tag.sh b/t/t7004-tag.sh index e689db42929..b41a47eb943 100755 --- a/t/t7004-tag.sh +++ b/t/t7004-tag.sh @@ -1862,6 +1862,51 @@ test_expect_success 'option override configured sort' ' test_cmp expect actual ' +test_expect_success '--no-sort cancels config sort keys' ' + test_config tag.sort "-refname" && + + # objecttype is identical for all of them, so sort falls back on + # default (ascending refname) + git tag -l \ + --no-sort \ + --sort="objecttype" \ + "foo*" >actual && + cat >expect <<-\EOF && + foo1.10 + foo1.3 + foo1.6 + EOF + test_cmp expect actual +' + +test_expect_success '--no-sort cancels command line sort keys' ' + # objecttype is identical for all of them, so sort falls back on + # default (ascending refname) + git tag -l \ + --sort="-refname" \ + --no-sort \ + --sort="objecttype" \ + "foo*" >actual && + cat >expect <<-\EOF && + foo1.10 + foo1.3 + foo1.6 + EOF + test_cmp expect actual +' + +test_expect_success '--no-sort without subsequent --sort prints expected tags' ' + # Sort the results with `sort` for a consistent comparison against + # expected + git tag -l --no-sort "foo*" | sort >actual && + cat >expect <<-\EOF && + foo1.10 + foo1.3 + foo1.6 + EOF + test_cmp expect actual +' + test_expect_success 'invalid sort parameter on command line' ' test_must_fail git tag -l --sort=notvalid "foo*" >actual ' From patchwork Tue Nov 14 19:53:50 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Victoria Dye X-Patchwork-Id: 13455823 Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 63A6B26ADB for ; Tue, 14 Nov 2023 19:54:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="H1yQHaJ5" Received: from mail-yw1-x112a.google.com (mail-yw1-x112a.google.com [IPv6:2607:f8b0:4864:20::112a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D2726E6 for ; Tue, 14 Nov 2023 11:54:06 -0800 (PST) Received: by mail-yw1-x112a.google.com with SMTP id 00721157ae682-5a7b91faf40so70084607b3.1 for ; Tue, 14 Nov 2023 11:54:06 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1699991645; x=1700596445; darn=vger.kernel.org; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:from:to:cc:subject:date :message-id:reply-to; bh=H/ky/3AXZvzs39bJrJJY3vV8N3LWOoVZM5pazlpvi0g=; b=H1yQHaJ5wZF3FcabgoSQK5/KhP62Tmk4NZKKMM+lN2x3/S1lrvEfNZIWLG5Q3Rx4Cj 8Tlr8MhPC+EiKaMW15Ius1G0fhYF8CtGGTbO03hqvFFbWvPyu8/hmvCE+G7LT3SZvJDP 9OUOoqyEC1/im2qcUH4qAIlL2nNFclcLpmTchjJLqX9ATFT3VFqawTKm5eWpUKqbxuXx oDDx3yzmJsHH+sdy7X3LyMSQWoUMhBkEDXLl6SHFEW79D/PfawCqYsNRhflgWyNi84Ez qK4jazKlf53XfvrNSTiDnhJaa3rqOK/U0Tl+XQuhNvrlZ/mDJZzf7QhSEkFJwKZlJl6K sJfQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1699991645; x=1700596445; 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 :subject:date:message-id:reply-to; bh=H/ky/3AXZvzs39bJrJJY3vV8N3LWOoVZM5pazlpvi0g=; b=e21bAofvc5PyeG0U8PNcOTyjfcUCVsmYq9aJmRn/OoO4xHKZFcLe62gTD2UZ97+p7g 8P8vapE1WuHBCPmDPM1QqMX31uMq+x5Yxq7RitlfnmXOjEuxXEiXP7VAnqstF/mPBnN9 F1wQStQn4KFXJd0XVVAkc8GWp2C5gVl65olZmxUXKAKAKy03mg2PuLRsXsZpnC50EbWy k45r2oId94pjR0Tg5QE/CKkIiagFp0rD6tHz85YwhpoCvkXyCo4yJQcPe6DOl32RylB7 zEhzoZvHT8SXQrcYTgvb6XccpiWCvZhgv9Jw33Rp98lADi1uW61ffX08/kTiJc12k2nr fohA== X-Gm-Message-State: AOJu0Yz5rPx4PBwdpMcluA67voPnPHj7TI4u/4cAenix6WR6vZYyki+A rs6XUHD6XonOrOrHtM5LhtBHzMo7AKc= X-Google-Smtp-Source: AGHT+IGq3GYUK9uzW0U32uvfd6NnlEDnikz/xkdEglSd/pvssuNxnjXAxD5+MVU4XCkBHCStWQZcGA== X-Received: by 2002:a0d:d613:0:b0:585:ef4e:6d93 with SMTP id y19-20020a0dd613000000b00585ef4e6d93mr11005278ywd.47.1699991645296; Tue, 14 Nov 2023 11:54:05 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id x20-20020a05620a0b5400b0077bda014d8esm2535055qkg.87.2023.11.14.11.54.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 14 Nov 2023 11:54:04 -0800 (PST) Message-ID: In-Reply-To: References: Date: Tue, 14 Nov 2023 19:53:50 +0000 Subject: [PATCH v2 02/10] ref-filter.h: add max_count and omit_empty to ref_format Fcc: Sent Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 To: git@vger.kernel.org Cc: Patrick Steinhardt , =?utf-8?q?=C3=98ystein?= Walle , Kristoffer Haugsbakk , Victoria Dye , Victoria Dye From: Victoria Dye From: Victoria Dye Add an internal 'array_opts' struct to 'struct ref_format' containing formatting options that pertain to the formatting of an entire ref array: 'max_count' and 'omit_empty'. These values are specified by the '--count' and '--omit-empty' options, respectively, to 'for-each-ref'/'tag'/'branch'. Storing these values in the 'ref_format' will simplify the consolidation of ref array formatting logic across builtins in later patches. Signed-off-by: Victoria Dye Acked-by: Øystein Walle --- builtin/branch.c | 5 ++--- builtin/for-each-ref.c | 21 +++++++++++---------- builtin/tag.c | 5 ++--- ref-filter.h | 5 +++++ 4 files changed, 20 insertions(+), 16 deletions(-) diff --git a/builtin/branch.c b/builtin/branch.c index d67738bbcaa..5a1ec1cd04f 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -45,7 +45,6 @@ static const char *head; static struct object_id head_oid; static int recurse_submodules = 0; static int submodule_propagate_branches = 0; -static int omit_empty = 0; static int branch_use_color = -1; static char branch_colors[][COLOR_MAXLEN] = { @@ -480,7 +479,7 @@ static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sortin string_list_append(output, out.buf); } else { fwrite(out.buf, 1, out.len, stdout); - if (out.len || !omit_empty) + if (out.len || !format->array_opts.omit_empty) putchar('\n'); } } @@ -737,7 +736,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix) OPT_BIT('D', NULL, &delete, N_("delete branch (even if not merged)"), 2), OPT_BIT('m', "move", &rename, N_("move/rename a branch and its reflog"), 1), OPT_BIT('M', NULL, &rename, N_("move/rename a branch, even if target exists"), 2), - OPT_BOOL(0, "omit-empty", &omit_empty, + OPT_BOOL(0, "omit-empty", &format.array_opts.omit_empty, N_("do not output a newline after empty formatted refs")), OPT_BIT('c', "copy", ©, N_("copy a branch and its reflog"), 1), OPT_BIT('C', NULL, ©, N_("copy a branch, even if target exists"), 2), diff --git a/builtin/for-each-ref.c b/builtin/for-each-ref.c index 93b370f550b..881c3ee055f 100644 --- a/builtin/for-each-ref.c +++ b/builtin/for-each-ref.c @@ -19,10 +19,10 @@ static char const * const for_each_ref_usage[] = { int cmd_for_each_ref(int argc, const char **argv, const char *prefix) { - int i; + int i, total; struct ref_sorting *sorting; struct string_list sorting_options = STRING_LIST_INIT_DUP; - int maxcount = 0, icase = 0, omit_empty = 0; + int icase = 0; struct ref_array array; struct ref_filter filter = REF_FILTER_INIT; struct ref_format format = REF_FORMAT_INIT; @@ -40,11 +40,11 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix) N_("quote placeholders suitably for python"), QUOTE_PYTHON), OPT_BIT(0 , "tcl", &format.quote_style, N_("quote placeholders suitably for Tcl"), QUOTE_TCL), - OPT_BOOL(0, "omit-empty", &omit_empty, + OPT_BOOL(0, "omit-empty", &format.array_opts.omit_empty, N_("do not output a newline after empty formatted refs")), OPT_GROUP(""), - OPT_INTEGER( 0 , "count", &maxcount, N_("show only matched refs")), + OPT_INTEGER( 0 , "count", &format.array_opts.max_count, N_("show only matched refs")), OPT_STRING( 0 , "format", &format.format, N_("format"), N_("format to use for the output")), OPT__COLOR(&format.use_color, N_("respect format colors")), OPT_REF_FILTER_EXCLUDE(&filter), @@ -71,8 +71,8 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix) string_list_append(&sorting_options, "refname"); parse_options(argc, argv, prefix, opts, for_each_ref_usage, 0); - if (maxcount < 0) { - error("invalid --count argument: `%d'", maxcount); + if (format.array_opts.max_count < 0) { + error("invalid --count argument: `%d'", format.array_opts.max_count); usage_with_options(for_each_ref_usage, opts); } if (HAS_MULTI_BITS(format.quote_style)) { @@ -109,15 +109,16 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix) ref_array_sort(sorting, &array); - if (!maxcount || array.nr < maxcount) - maxcount = array.nr; - for (i = 0; i < maxcount; i++) { + total = format.array_opts.max_count; + if (!total || array.nr < total) + total = array.nr; + for (i = 0; i < total; i++) { strbuf_reset(&err); strbuf_reset(&output); if (format_ref_array_item(array.items[i], &format, &output, &err)) die("%s", err.buf); fwrite(output.buf, 1, output.len, stdout); - if (output.len || !omit_empty) + if (output.len || !format.array_opts.omit_empty) putchar('\n'); } diff --git a/builtin/tag.c b/builtin/tag.c index 64f3196cd4c..2d599245d48 100644 --- a/builtin/tag.c +++ b/builtin/tag.c @@ -44,7 +44,6 @@ static const char * const git_tag_usage[] = { static unsigned int colopts; static int force_sign_annotate; static int config_sign_tag = -1; /* unspecified */ -static int omit_empty = 0; static int list_tags(struct ref_filter *filter, struct ref_sorting *sorting, struct ref_format *format) @@ -83,7 +82,7 @@ static int list_tags(struct ref_filter *filter, struct ref_sorting *sorting, if (format_ref_array_item(array.items[i], format, &output, &err)) die("%s", err.buf); fwrite(output.buf, 1, output.len, stdout); - if (output.len || !omit_empty) + if (output.len || !format->array_opts.omit_empty) putchar('\n'); } @@ -481,7 +480,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix) OPT_WITHOUT(&filter.no_commit, N_("print only tags that don't contain the commit")), OPT_MERGED(&filter, N_("print only tags that are merged")), OPT_NO_MERGED(&filter, N_("print only tags that are not merged")), - OPT_BOOL(0, "omit-empty", &omit_empty, + OPT_BOOL(0, "omit-empty", &format.array_opts.omit_empty, N_("do not output a newline after empty formatted refs")), OPT_REF_SORT(&sorting_options), { diff --git a/ref-filter.h b/ref-filter.h index 1524bc463a5..d87d61238b7 100644 --- a/ref-filter.h +++ b/ref-filter.h @@ -92,6 +92,11 @@ struct ref_format { /* List of bases for ahead-behind counts. */ struct string_list bases; + + struct { + int max_count; + int omit_empty; + } array_opts; }; #define REF_FILTER_INIT { \ From patchwork Tue Nov 14 19:53:51 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victoria Dye X-Patchwork-Id: 13455824 Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B1B4326AE9 for ; Tue, 14 Nov 2023 19:54:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="mXtSLmkD" Received: from mail-qk1-x729.google.com (mail-qk1-x729.google.com [IPv6:2607:f8b0:4864:20::729]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4350C107 for ; Tue, 14 Nov 2023 11:54:08 -0800 (PST) Received: by mail-qk1-x729.google.com with SMTP id af79cd13be357-7788f727dd7so365931185a.1 for ; Tue, 14 Nov 2023 11:54:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1699991647; x=1700596447; darn=vger.kernel.org; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:from:to:cc:subject:date :message-id:reply-to; bh=AG46S1jgdc9M9daQ26TOOGr5yuGxoXVZ/FvR7gcs3AA=; b=mXtSLmkDxNlesBeV+OvjecIH8Hok5mvr1wkxeouiwCrPAT3j6nlhoqAyex/RCa8TYv mzug8Vb1VQGa5nazt+Mpj4oweSegtUud4XNATozEqbqH9xw1vjTr+qWGdxRA1x233Oyg c6x62SG8M+2wJe1Iujv+DnPSvZKjegCXpjPyMZAqeG/T/6jb3RJWSrnAMQA7uiJpILMu 2tk46rg8icVZ/NX4sOrGEzThZ2HoDZtKts8eTCdxGwuHGULWLOZ4ulZURGcSZ51W7xbB LRGm+6JTvf6rhIehjl7MUuhsMESHxXDSE3crKRh/3HFHW+I+w/MRJmd2KD0tksia+pSf Hi/w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1699991647; x=1700596447; 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 :subject:date:message-id:reply-to; bh=AG46S1jgdc9M9daQ26TOOGr5yuGxoXVZ/FvR7gcs3AA=; b=F/2Ea5joQCAxaBM7OineGy50x1wbJqz3BzDIAGmc0WlSLToVMH00t1ouspkE2xf77l LEaxOrpKpwTCBWUpNOUUI3xt9Yu1p0/n2f1EJSM44iIxYZFnpKbkdHY15YEzJX9eKPs1 Ahatq2TFIHCuSffd8DroMukjRADOM+JeeIzPkQCxm2H5slsGSlt0l88JLoAmPnIzDEfn xkZgORbnBz4+gl3PR8i8XmA9b4Rdjz6cMeVwMHCzMfnlGolw8pIGDrEcaVWIe3x0Xys1 am9LmN2/akxSIg7t8Lib5Br3ARCVWqlZUiMyMH6wFI1WuEucOQCzUWQKd+v51p7+cKdH lmdg== X-Gm-Message-State: AOJu0YyLpeInrpjJYrbdQDoGKDlz1OqMmqL/q+7XFek/QZkuCqwUbvsn SfUBSh5MsE8+8Np/VPJ8+KJv03CrxB8= X-Google-Smtp-Source: AGHT+IGXWLbCY0ZI8BHB6Ygr2LIw//lFtLVwb1V9PzU74Mhvd9uBdi4W3j11aKQRHj2SFwzYIAjnug== X-Received: by 2002:a05:6214:5c5:b0:66d:b8bf:d9e8 with SMTP id t5-20020a05621405c500b0066db8bfd9e8mr3450715qvz.4.1699991647120; Tue, 14 Nov 2023 11:54:07 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id ff18-20020a0562140bd200b00675497e5bf3sm3172880qvb.30.2023.11.14.11.54.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 14 Nov 2023 11:54:06 -0800 (PST) Message-ID: In-Reply-To: References: Date: Tue, 14 Nov 2023 19:53:51 +0000 Subject: [PATCH v2 03/10] ref-filter.h: move contains caches into filter Fcc: Sent Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 To: git@vger.kernel.org Cc: Patrick Steinhardt , =?utf-8?q?=C3=98ystein?= Walle , Kristoffer Haugsbakk , Victoria Dye , Victoria Dye From: Victoria Dye From: Victoria Dye Move the 'contains_cache' and 'no_contains_cache' used in filter_refs into an 'internal' struct of the 'struct ref_filter'. In later patches, the 'struct ref_filter *' will be a common data structure across multiple filtering functions. These caches are part of the common functionality the filter struct will support, so they are updated to be internally accessible wherever the filter is used. The design used here mirrors what was introduced in 576de3d956 (unpack_trees: start splitting internal fields from public API, 2023-02-27) for 'unpack_trees_options'. Signed-off-by: Victoria Dye --- ref-filter.c | 14 ++++++-------- ref-filter.h | 6 ++++++ 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/ref-filter.c b/ref-filter.c index 7250089b7c6..5129b6986c9 100644 --- a/ref-filter.c +++ b/ref-filter.c @@ -2764,8 +2764,6 @@ static int filter_ref_kind(struct ref_filter *filter, const char *refname) struct ref_filter_cbdata { struct ref_array *array; struct ref_filter *filter; - struct contains_cache contains_cache; - struct contains_cache no_contains_cache; }; /* @@ -2816,11 +2814,11 @@ static int ref_filter_handler(const char *refname, const struct object_id *oid, return 0; /* We perform the filtering for the '--contains' option... */ if (filter->with_commit && - !commit_contains(filter, commit, filter->with_commit, &ref_cbdata->contains_cache)) + !commit_contains(filter, commit, filter->with_commit, &filter->internal.contains_cache)) return 0; /* ...or for the `--no-contains' option */ if (filter->no_commit && - commit_contains(filter, commit, filter->no_commit, &ref_cbdata->no_contains_cache)) + commit_contains(filter, commit, filter->no_commit, &filter->internal.no_contains_cache)) return 0; } @@ -2989,8 +2987,8 @@ int filter_refs(struct ref_array *array, struct ref_filter *filter, unsigned int save_commit_buffer_orig = save_commit_buffer; save_commit_buffer = 0; - init_contains_cache(&ref_cbdata.contains_cache); - init_contains_cache(&ref_cbdata.no_contains_cache); + init_contains_cache(&filter->internal.contains_cache); + init_contains_cache(&filter->internal.no_contains_cache); /* Simple per-ref filtering */ if (!filter->kind) @@ -3014,8 +3012,8 @@ int filter_refs(struct ref_array *array, struct ref_filter *filter, unsigned int head_ref(ref_filter_handler, &ref_cbdata); } - clear_contains_cache(&ref_cbdata.contains_cache); - clear_contains_cache(&ref_cbdata.no_contains_cache); + clear_contains_cache(&filter->internal.contains_cache); + clear_contains_cache(&filter->internal.no_contains_cache); /* Filters that need revision walking */ reach_filter(array, &filter->reachable_from, INCLUDE_REACHED); diff --git a/ref-filter.h b/ref-filter.h index d87d61238b7..0db3ff52889 100644 --- a/ref-filter.h +++ b/ref-filter.h @@ -7,6 +7,7 @@ #include "commit.h" #include "string-list.h" #include "strvec.h" +#include "commit-reach.h" /* Quoting styles */ #define QUOTE_NONE 0 @@ -75,6 +76,11 @@ struct ref_filter { lines; int abbrev, verbose; + + struct { + struct contains_cache contains_cache; + struct contains_cache no_contains_cache; + } internal; }; struct ref_format { From patchwork Tue Nov 14 19:53:52 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victoria Dye X-Patchwork-Id: 13455825 Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 184962FC22 for ; Tue, 14 Nov 2023 19:54:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="LGswV3rf" Received: from mail-qk1-x733.google.com (mail-qk1-x733.google.com [IPv6:2607:f8b0:4864:20::733]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 23E9710E for ; Tue, 14 Nov 2023 11:54:10 -0800 (PST) Received: by mail-qk1-x733.google.com with SMTP id af79cd13be357-77ba6d5123fso12389085a.0 for ; Tue, 14 Nov 2023 11:54:10 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1699991649; x=1700596449; darn=vger.kernel.org; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:from:to:cc:subject:date :message-id:reply-to; bh=y09QspDXVPmlBRm1qFdY7UtSS881c75ebgMZNDaEc1c=; b=LGswV3rf13KDgHrNSLrGHpSGjOCUJOmKt9ssK7UwxKphFzWAype6fJBbVx0FeMTXJx O05X0BmZ7JfTt5iVlYVxwOBis18DWLvQtJZRH1M5fTWvgcHmPtYUcEL+CdlBcs5bAbQy Xwm/PM8fOfhyEXoQa58PZ1e1/9yYipHBjs+RRUTEKUbUAc2PybIFtGatNskW7246Y+Wt cAg23kI9PB32sZs1RQBws/pUMF1fRZdoSfWZmeod3cBDiAQJnWWsnXmfYx0tfTHlYfmH MWlCoRvI1hnroNVa9v74cu7E4tv/7Hbif07CKSBv7BWTDI1vV4NsVr5q/HQYqbYpMA6T 9/UA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1699991649; x=1700596449; 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 :subject:date:message-id:reply-to; bh=y09QspDXVPmlBRm1qFdY7UtSS881c75ebgMZNDaEc1c=; b=f7nGl7PEWKMFjMaqKbSMblEeuGSrLj010rmktmafoYnT8FmSCg9o/1Gr+vAY5dPPWT lyNKEO1DXNDlHOQb56p+G7l81sJyW7uz8dGazbbxQcJoix8HZI8K4Uxdb2sX2w4Q0zsz Do7qtnlPAoZElWFJi4W8ZmXYt5kVZ3VXoyJNit5/UzmAqnDfpLDc221m4+YsNmYbD3+D KH3jDyY9XUd8DpOYmBtvi9EclwGotwOXcnWq5QAH0GyUXrhSQlQxBEReFoIEx9hiyKM+ X9xgxctH4Y8AzP+9UFFupqrtp/4Xz0RVicxGR39LNMM8qPYbiAh0Iw6e/C8Q5j8YLwbw xaRQ== X-Gm-Message-State: AOJu0YzIpZ9vkxFUsy8B3xxMEW+PmqVlYoWsYKAS+Q5KwqWonaFXTINT C5gUpAWXUsvE/90FPOxuTb0dNBlMTag= X-Google-Smtp-Source: AGHT+IHneOkl8xj9dMwHnCdoefib/9QTCysyzDMgnDQXbCOAUBFuJxF+nt3SC1CTJcqXOpFVGlNTIw== X-Received: by 2002:a05:620a:1a1b:b0:774:2afe:97c4 with SMTP id bk27-20020a05620a1a1b00b007742afe97c4mr5640489qkb.12.1699991648905; Tue, 14 Nov 2023 11:54:08 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id py17-20020a05620a879100b00767d6ec578csm2905993qkn.20.2023.11.14.11.54.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 14 Nov 2023 11:54:08 -0800 (PST) Message-ID: <187b1d6610f96ba16bb7e1ff80d1c994a67b8753.1699991638.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Tue, 14 Nov 2023 19:53:52 +0000 Subject: [PATCH v2 04/10] ref-filter.h: add functions for filter/format & format-only Fcc: Sent Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 To: git@vger.kernel.org Cc: Patrick Steinhardt , =?utf-8?q?=C3=98ystein?= Walle , Kristoffer Haugsbakk , Victoria Dye , Victoria Dye From: Victoria Dye From: Victoria Dye Add two new public methods to 'ref-filter.h': * 'print_formatted_ref_array()' which, given a format specification & array of ref items, formats and prints the items to stdout. * 'filter_and_format_refs()' which combines 'filter_refs()', 'ref_array_sort()', and 'print_formatted_ref_array()' into a single function. This consolidates much of the code used to filter and format refs in 'builtin/for-each-ref.c', 'builtin/tag.c', and 'builtin/branch.c', reducing duplication and simplifying the future changes needed to optimize the filter & format process. Signed-off-by: Victoria Dye --- builtin/branch.c | 33 +++++++++++++++++---------------- builtin/for-each-ref.c | 27 +-------------------------- builtin/tag.c | 23 +---------------------- ref-filter.c | 35 +++++++++++++++++++++++++++++++++++ ref-filter.h | 14 ++++++++++++++ 5 files changed, 68 insertions(+), 64 deletions(-) diff --git a/builtin/branch.c b/builtin/branch.c index 5a1ec1cd04f..2ed59f16f1c 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -437,8 +437,6 @@ static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sortin { int i; struct ref_array array; - struct strbuf out = STRBUF_INIT; - struct strbuf err = STRBUF_INIT; int maxwidth = 0; const char *remote_prefix = ""; char *to_free = NULL; @@ -468,24 +466,27 @@ static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sortin filter_ahead_behind(the_repository, format, &array); ref_array_sort(sorting, &array); - for (i = 0; i < array.nr; i++) { - strbuf_reset(&err); - strbuf_reset(&out); - if (format_ref_array_item(array.items[i], format, &out, &err)) - die("%s", err.buf); - if (column_active(colopts)) { - assert(!filter->verbose && "--column and --verbose are incompatible"); - /* format to a string_list to let print_columns() do its job */ + if (column_active(colopts)) { + struct strbuf out = STRBUF_INIT, err = STRBUF_INIT; + + assert(!filter->verbose && "--column and --verbose are incompatible"); + + for (i = 0; i < array.nr; i++) { + strbuf_reset(&err); + strbuf_reset(&out); + if (format_ref_array_item(array.items[i], format, &out, &err)) + die("%s", err.buf); + + /* format to a string_list to let print_columns() do its job */ string_list_append(output, out.buf); - } else { - fwrite(out.buf, 1, out.len, stdout); - if (out.len || !format->array_opts.omit_empty) - putchar('\n'); } + + strbuf_release(&err); + strbuf_release(&out); + } else { + print_formatted_ref_array(&array, format); } - strbuf_release(&err); - strbuf_release(&out); ref_array_clear(&array); free(to_free); } diff --git a/builtin/for-each-ref.c b/builtin/for-each-ref.c index 881c3ee055f..1c19cd5bd34 100644 --- a/builtin/for-each-ref.c +++ b/builtin/for-each-ref.c @@ -19,15 +19,11 @@ static char const * const for_each_ref_usage[] = { int cmd_for_each_ref(int argc, const char **argv, const char *prefix) { - int i, total; struct ref_sorting *sorting; struct string_list sorting_options = STRING_LIST_INIT_DUP; int icase = 0; - struct ref_array array; struct ref_filter filter = REF_FILTER_INIT; struct ref_format format = REF_FORMAT_INIT; - struct strbuf output = STRBUF_INIT; - struct strbuf err = STRBUF_INIT; int from_stdin = 0; struct strvec vec = STRVEC_INIT; @@ -61,8 +57,6 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix) OPT_END(), }; - memset(&array, 0, sizeof(array)); - format.format = "%(objectname) %(objecttype)\t%(refname)"; git_config(git_default_config, NULL); @@ -104,27 +98,8 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix) } filter.match_as_path = 1; - filter_refs(&array, &filter, FILTER_REFS_ALL); - filter_ahead_behind(the_repository, &format, &array); - - ref_array_sort(sorting, &array); - - total = format.array_opts.max_count; - if (!total || array.nr < total) - total = array.nr; - for (i = 0; i < total; i++) { - strbuf_reset(&err); - strbuf_reset(&output); - if (format_ref_array_item(array.items[i], &format, &output, &err)) - die("%s", err.buf); - fwrite(output.buf, 1, output.len, stdout); - if (output.len || !format.array_opts.omit_empty) - putchar('\n'); - } + filter_and_format_refs(&filter, FILTER_REFS_ALL, sorting, &format); - strbuf_release(&err); - strbuf_release(&output); - ref_array_clear(&array); ref_filter_clear(&filter); ref_sorting_release(sorting); strvec_clear(&vec); diff --git a/builtin/tag.c b/builtin/tag.c index 2d599245d48..2528d499dd8 100644 --- a/builtin/tag.c +++ b/builtin/tag.c @@ -48,13 +48,7 @@ static int config_sign_tag = -1; /* unspecified */ static int list_tags(struct ref_filter *filter, struct ref_sorting *sorting, struct ref_format *format) { - struct ref_array array; - struct strbuf output = STRBUF_INIT; - struct strbuf err = STRBUF_INIT; char *to_free = NULL; - int i; - - memset(&array, 0, sizeof(array)); if (filter->lines == -1) filter->lines = 0; @@ -72,23 +66,8 @@ static int list_tags(struct ref_filter *filter, struct ref_sorting *sorting, if (verify_ref_format(format)) die(_("unable to parse format string")); filter->with_commit_tag_algo = 1; - filter_refs(&array, filter, FILTER_REFS_TAGS); - filter_ahead_behind(the_repository, format, &array); - ref_array_sort(sorting, &array); - - for (i = 0; i < array.nr; i++) { - strbuf_reset(&output); - strbuf_reset(&err); - if (format_ref_array_item(array.items[i], format, &output, &err)) - die("%s", err.buf); - fwrite(output.buf, 1, output.len, stdout); - if (output.len || !format->array_opts.omit_empty) - putchar('\n'); - } + filter_and_format_refs(filter, FILTER_REFS_TAGS, sorting, format); - strbuf_release(&err); - strbuf_release(&output); - ref_array_clear(&array); free(to_free); return 0; diff --git a/ref-filter.c b/ref-filter.c index 5129b6986c9..8992fbf45b1 100644 --- a/ref-filter.c +++ b/ref-filter.c @@ -3023,6 +3023,18 @@ int filter_refs(struct ref_array *array, struct ref_filter *filter, unsigned int return ret; } +void filter_and_format_refs(struct ref_filter *filter, unsigned int type, + struct ref_sorting *sorting, + struct ref_format *format) +{ + struct ref_array array = { 0 }; + filter_refs(&array, filter, type); + filter_ahead_behind(the_repository, format, &array); + ref_array_sort(sorting, &array); + print_formatted_ref_array(&array, format); + ref_array_clear(&array); +} + static int compare_detached_head(struct ref_array_item *a, struct ref_array_item *b) { if (!(a->kind ^ b->kind)) @@ -3212,6 +3224,29 @@ int format_ref_array_item(struct ref_array_item *info, return 0; } +void print_formatted_ref_array(struct ref_array *array, struct ref_format *format) +{ + int total; + struct strbuf output = STRBUF_INIT, err = STRBUF_INIT; + + total = format->array_opts.max_count; + if (!total || array->nr < total) + total = array->nr; + for (int i = 0; i < total; i++) { + strbuf_reset(&err); + strbuf_reset(&output); + if (format_ref_array_item(array->items[i], format, &output, &err)) + die("%s", err.buf); + if (output.len || !format->array_opts.omit_empty) { + fwrite(output.buf, 1, output.len, stdout); + putchar('\n'); + } + } + + strbuf_release(&err); + strbuf_release(&output); +} + void pretty_print_ref(const char *name, const struct object_id *oid, struct ref_format *format) { diff --git a/ref-filter.h b/ref-filter.h index 0db3ff52889..0ce5af58ab3 100644 --- a/ref-filter.h +++ b/ref-filter.h @@ -137,6 +137,14 @@ struct ref_format { * filtered refs in the ref_array structure. */ int filter_refs(struct ref_array *array, struct ref_filter *filter, unsigned int type); +/* + * Filter refs using the given ref_filter and type, sort the contents + * according to the given ref_sorting, format the filtered refs with the + * given ref_format, and print them to stdout. + */ +void filter_and_format_refs(struct ref_filter *filter, unsigned int type, + struct ref_sorting *sorting, + struct ref_format *format); /* Clear all memory allocated to ref_array */ void ref_array_clear(struct ref_array *array); /* Used to verify if the given format is correct and to parse out the used atoms */ @@ -161,6 +169,12 @@ char *get_head_description(void); /* Set up translated strings in the output. */ void setup_ref_filter_porcelain_msg(void); +/* + * Print up to maxcount ref_array elements to stdout using the given + * ref_format. + */ +void print_formatted_ref_array(struct ref_array *array, struct ref_format *format); + /* * Print a single ref, outside of any ref-filter. Note that the * name must be a fully qualified refname. From patchwork Tue Nov 14 19:53:53 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victoria Dye X-Patchwork-Id: 13455826 Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8ADAB2FC2D for ; Tue, 14 Nov 2023 19:54:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="OwSbU4F4" Received: from mail-yb1-xb35.google.com (mail-yb1-xb35.google.com [IPv6:2607:f8b0:4864:20::b35]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 638BE102 for ; Tue, 14 Nov 2023 11:54:12 -0800 (PST) Received: by mail-yb1-xb35.google.com with SMTP id 3f1490d57ef6-da7238b3eb4so6552938276.1 for ; Tue, 14 Nov 2023 11:54:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1699991651; x=1700596451; darn=vger.kernel.org; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:from:to:cc:subject:date :message-id:reply-to; bh=Xd4IpdCEHxKY34PcwA7ZtdeQFczqMO6R4iJjYlLTNv8=; b=OwSbU4F4jFq2tMiK73ydYZDINjIBFsV8P2BlBvt/MT4MfA5c5Av58RkCguMGvtkvoq VQNBdLpsJvktUmg79vKHyeDHOQp2K3xTox3n3/CEEC1Cj0nPFPutKiAqBkj2iQa19l6s lF+7kyC8QB6ZKJ+G266u8kpWcDXFfSmAA/2WKkM3gHw4kH5lCYFj8st/ZyGQOan1SuwI /KjSy1BQqWMfKONHlhkYVCO9DH8x4YFC1HZp/vjS+D9y0gRA3MQ3bmvdTmtzvXQ51A8o XHWR1AN6xsf+XY+zLd7w5DvB+wUFTML/7khq1bBuy/252TP2K/fAjXvR1PkwkrI9koWM y7AA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1699991651; x=1700596451; 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 :subject:date:message-id:reply-to; bh=Xd4IpdCEHxKY34PcwA7ZtdeQFczqMO6R4iJjYlLTNv8=; b=YyIIk6TYgvY8ZZq5fVDURpp2PLQ7oei2naaez8WifNyS2Wjs3miegq+nUO826dtS39 1Ly9+ok+2gkaGGfAHdrZvFb6nztg+TO4pafwEIXHDUpuSuPdTyHKKPxJMxz4o4Ff2Ci5 4sLkks7vYdmKwGW7ucqTGZcuLpp9K/OMtntC+Mh3e5lcIw0vXF+eaWnDM9KiEZbxE2HI C+GWDNOWunHt4WqYfrjqJ/w2z2xclWLb8uNLTDqr5vKx+KaqSHKzD3n215FkajDtrvsQ bSgIxmE4keiTRHV1//1c3KB4BZQZT194mtjoK93s67uTOOQ+InpvnPrg8Y05PGlvvmy3 2GPA== X-Gm-Message-State: AOJu0YxYR+cnGGhglmnXGQKvp3lg/Hov6j+1boTuXrnY2Ari7E3hnVHr qCSp5u4+g68J6/LTeQDiiRutsrDz/XU= X-Google-Smtp-Source: AGHT+IHFdidTKAQyW67J8dfMmcv9/VpFWNibD+TcEstubITdfHEVcHIzRgOMQlJs2vzWS13Mk201YA== X-Received: by 2002:a25:cc8:0:b0:dae:b67e:7cd4 with SMTP id 191-20020a250cc8000000b00daeb67e7cd4mr9722595ybm.46.1699991650708; Tue, 14 Nov 2023 11:54:10 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id d5-20020a05620a158500b007756e75b91bsm2889265qkk.78.2023.11.14.11.54.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 14 Nov 2023 11:54:10 -0800 (PST) Message-ID: <040d291ca458ef0068e3fd543e7f441b2e5e71ad.1699991638.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Tue, 14 Nov 2023 19:53:53 +0000 Subject: [PATCH v2 05/10] ref-filter.c: rename 'ref_filter_handler()' to 'filter_one()' Fcc: Sent Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 To: git@vger.kernel.org Cc: Patrick Steinhardt , =?utf-8?q?=C3=98ystein?= Walle , Kristoffer Haugsbakk , Victoria Dye , Victoria Dye From: Victoria Dye From: Victoria Dye Rename 'ref_filter_handler()' to 'filter_one()' to more clearly distinguish it from other ref filtering callbacks that will be added in later patches. The "*_one()" naming convention is common throughout the codebase for iteration callbacks. Signed-off-by: Victoria Dye --- ref-filter.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ref-filter.c b/ref-filter.c index 8992fbf45b1..5186ee2687b 100644 --- a/ref-filter.c +++ b/ref-filter.c @@ -2770,7 +2770,7 @@ struct ref_filter_cbdata { * A call-back given to for_each_ref(). Filter refs and keep them for * later object processing. */ -static int ref_filter_handler(const char *refname, const struct object_id *oid, int flag, void *cb_data) +static int filter_one(const char *refname, const struct object_id *oid, int flag, void *cb_data) { struct ref_filter_cbdata *ref_cbdata = cb_data; struct ref_filter *filter = ref_cbdata->filter; @@ -3001,15 +3001,15 @@ int filter_refs(struct ref_array *array, struct ref_filter *filter, unsigned int * of filter_ref_kind(). */ if (filter->kind == FILTER_REFS_BRANCHES) - ret = for_each_fullref_in("refs/heads/", ref_filter_handler, &ref_cbdata); + ret = for_each_fullref_in("refs/heads/", filter_one, &ref_cbdata); else if (filter->kind == FILTER_REFS_REMOTES) - ret = for_each_fullref_in("refs/remotes/", ref_filter_handler, &ref_cbdata); + ret = for_each_fullref_in("refs/remotes/", filter_one, &ref_cbdata); else if (filter->kind == FILTER_REFS_TAGS) - ret = for_each_fullref_in("refs/tags/", ref_filter_handler, &ref_cbdata); + ret = for_each_fullref_in("refs/tags/", filter_one, &ref_cbdata); else if (filter->kind & FILTER_REFS_ALL) - ret = for_each_fullref_in_pattern(filter, ref_filter_handler, &ref_cbdata); + ret = for_each_fullref_in_pattern(filter, filter_one, &ref_cbdata); if (!ret && (filter->kind & FILTER_REFS_DETACHED_HEAD)) - head_ref(ref_filter_handler, &ref_cbdata); + head_ref(filter_one, &ref_cbdata); } clear_contains_cache(&filter->internal.contains_cache); From patchwork Tue Nov 14 19:53:54 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victoria Dye X-Patchwork-Id: 13455827 Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8AA892FC3F for ; Tue, 14 Nov 2023 19:54:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="B1T+OmwH" Received: from mail-qv1-xf32.google.com (mail-qv1-xf32.google.com [IPv6:2607:f8b0:4864:20::f32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1FFFCEB for ; Tue, 14 Nov 2023 11:54:14 -0800 (PST) Received: by mail-qv1-xf32.google.com with SMTP id 6a1803df08f44-66d24ccc6f2so1291006d6.0 for ; Tue, 14 Nov 2023 11:54:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1699991652; x=1700596452; darn=vger.kernel.org; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:from:to:cc:subject:date :message-id:reply-to; bh=Ch72ojuVCuaq6f8agFpDhGz2k0gHl0iioyjojQYsJR8=; b=B1T+OmwHFnmlkNTs7hVzioR26fqFv/ugF0HgQu7Gg+VvbCw54TO3/OgInfU4Qw6k2H 02YM5qMFJ9Xwsk4cDOdkdeEHCWFI/WCEo9Dgv2qx2JPyj+RqNwHBhuexMZ2TBlFVXBay JEvpqTlIKLwG6nYX4p0cjKhmctCwoahAZ24+qDDvZ/wBeO06IxcahozIYs/Ogylu7vKN z6oCtRzlC4qpJWwKlNuEVHfBPm64FnfGXshlUaZK6i8XjGG1y2VHoVj5ydwGAuKUPWWA sj4xhiZeZ0i1Qmxv0qWGCcp9PhCQ0qXtqcPAFyGIKPwjw05R7mLE3r9Tq1zbPSHBu4Jm AN+Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1699991652; x=1700596452; 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 :subject:date:message-id:reply-to; bh=Ch72ojuVCuaq6f8agFpDhGz2k0gHl0iioyjojQYsJR8=; b=ewku7HmTHIzEWwORcqlgYxxOqopvThwYeK2jVlc72KM3DNfDoLhmJvqjLzAP8nNaZ6 tk3iCraEqhL8t1gIQu0VyVDmVI91GYi/YmaDNUWlbtTh0RfcpHgjabnyQPr7NAWQngQM XpQoymPWboHQZALfJyV/4imOLotrnSo0veutni7KeSR2ibOvgGLMNL42JSDG+aazUJbj 34B6n82asbU25fnICfCaKnziH7uNNZ+Bgxg0EFR43Jlx+PaLYoSc17cLLJSSJ9Hkn2NV SnWYswBoRjWabYfH94107j6LtLgk5EvSwBVe0ZTvQGnx6+kEtZ2gcer8IQeThj/mbTif lM4Q== X-Gm-Message-State: AOJu0YwlfGeuR7Asr9Lm/sYQuuTPZKuvbVyrXSBH6zitmPZATdLa/mN1 eoWnvT27KBKB2V4172dAw1kD/8VKUcY= X-Google-Smtp-Source: AGHT+IFSUBG6hQCTuURCXQ9aa6DpilvHtgSFrdG7UlhSAM7sXqhTMuMfhZg3yXpMkqJjG1bp6XsCqQ== X-Received: by 2002:a05:6214:d06:b0:66d:8752:b6cf with SMTP id 6-20020a0562140d0600b0066d8752b6cfmr5860156qvh.26.1699991652486; Tue, 14 Nov 2023 11:54:12 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id c17-20020a0cd611000000b0064f4e0b2089sm3151014qvj.33.2023.11.14.11.54.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 14 Nov 2023 11:54:12 -0800 (PST) Message-ID: <633c0c74c2efb42e1491d53809a9825599690301.1699991638.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Tue, 14 Nov 2023 19:53:54 +0000 Subject: [PATCH v2 06/10] ref-filter.c: refactor to create common helper functions Fcc: Sent Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 To: git@vger.kernel.org Cc: Patrick Steinhardt , =?utf-8?q?=C3=98ystein?= Walle , Kristoffer Haugsbakk , Victoria Dye , Victoria Dye From: Victoria Dye From: Victoria Dye Factor out parts of 'ref_array_push()', 'ref_filter_handler()', and 'filter_refs()' into new helper functions: * Extract the code to grow a 'struct ref_array' and append a given 'struct ref_array_item *' to it from 'ref_array_push()' into 'ref_array_append()'. * Extract the code to filter a given ref by refname & object ID then create a new 'struct ref_array_item *' from 'filter_one()' into 'apply_ref_filter()'. * Extract the code for filter pre-processing, contains cache creation, and ref iteration from 'filter_refs()' into 'do_filter_refs()'. In later patches, these helpers will be used by new ref-filter API functions. This patch does not result in any user-facing behavior changes or changes to callers outside of 'ref-filter.c'. Signed-off-by: Victoria Dye --- ref-filter.c | 115 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 69 insertions(+), 46 deletions(-) diff --git a/ref-filter.c b/ref-filter.c index 5186ee2687b..ff00ab4b8d8 100644 --- a/ref-filter.c +++ b/ref-filter.c @@ -2716,15 +2716,18 @@ static struct ref_array_item *new_ref_array_item(const char *refname, return ref; } +static void ref_array_append(struct ref_array *array, struct ref_array_item *ref) +{ + ALLOC_GROW(array->items, array->nr + 1, array->alloc); + array->items[array->nr++] = ref; +} + struct ref_array_item *ref_array_push(struct ref_array *array, const char *refname, const struct object_id *oid) { struct ref_array_item *ref = new_ref_array_item(refname, oid); - - ALLOC_GROW(array->items, array->nr + 1, array->alloc); - array->items[array->nr++] = ref; - + ref_array_append(array, ref); return ref; } @@ -2761,46 +2764,36 @@ static int filter_ref_kind(struct ref_filter *filter, const char *refname) return ref_kind_from_refname(refname); } -struct ref_filter_cbdata { - struct ref_array *array; - struct ref_filter *filter; -}; - -/* - * A call-back given to for_each_ref(). Filter refs and keep them for - * later object processing. - */ -static int filter_one(const char *refname, const struct object_id *oid, int flag, void *cb_data) +static struct ref_array_item *apply_ref_filter(const char *refname, const struct object_id *oid, + int flag, struct ref_filter *filter) { - struct ref_filter_cbdata *ref_cbdata = cb_data; - struct ref_filter *filter = ref_cbdata->filter; struct ref_array_item *ref; struct commit *commit = NULL; unsigned int kind; if (flag & REF_BAD_NAME) { warning(_("ignoring ref with broken name %s"), refname); - return 0; + return NULL; } if (flag & REF_ISBROKEN) { warning(_("ignoring broken ref %s"), refname); - return 0; + return NULL; } /* Obtain the current ref kind from filter_ref_kind() and ignore unwanted refs. */ kind = filter_ref_kind(filter, refname); if (!(kind & filter->kind)) - return 0; + return NULL; if (!filter_pattern_match(filter, refname)) - return 0; + return NULL; if (filter_exclude_match(filter, refname)) - return 0; + return NULL; if (filter->points_at.nr && !match_points_at(&filter->points_at, oid, refname)) - return 0; + return NULL; /* * A merge filter is applied on refs pointing to commits. Hence @@ -2811,15 +2804,15 @@ static int filter_one(const char *refname, const struct object_id *oid, int flag filter->with_commit || filter->no_commit || filter->verbose) { commit = lookup_commit_reference_gently(the_repository, oid, 1); if (!commit) - return 0; + return NULL; /* We perform the filtering for the '--contains' option... */ if (filter->with_commit && !commit_contains(filter, commit, filter->with_commit, &filter->internal.contains_cache)) - return 0; + return NULL; /* ...or for the `--no-contains' option */ if (filter->no_commit && commit_contains(filter, commit, filter->no_commit, &filter->internal.no_contains_cache)) - return 0; + return NULL; } /* @@ -2827,11 +2820,32 @@ static int filter_one(const char *refname, const struct object_id *oid, int flag * to do its job and the resulting list may yet to be pruned * by maxcount logic. */ - ref = ref_array_push(ref_cbdata->array, refname, oid); + ref = new_ref_array_item(refname, oid); ref->commit = commit; ref->flag = flag; ref->kind = kind; + return ref; +} + +struct ref_filter_cbdata { + struct ref_array *array; + struct ref_filter *filter; +}; + +/* + * A call-back given to for_each_ref(). Filter refs and keep them for + * later object processing. + */ +static int filter_one(const char *refname, const struct object_id *oid, int flag, void *cb_data) +{ + struct ref_filter_cbdata *ref_cbdata = cb_data; + struct ref_array_item *ref; + + ref = apply_ref_filter(refname, oid, flag, ref_cbdata->filter); + if (ref) + ref_array_append(ref_cbdata->array, ref); + return 0; } @@ -2967,26 +2981,12 @@ void filter_ahead_behind(struct repository *r, free(commits); } -/* - * API for filtering a set of refs. Based on the type of refs the user - * has requested, we iterate through those refs and apply filters - * as per the given ref_filter structure and finally store the - * filtered refs in the ref_array structure. - */ -int filter_refs(struct ref_array *array, struct ref_filter *filter, unsigned int type) +static int do_filter_refs(struct ref_filter *filter, unsigned int type, each_ref_fn fn, void *cb_data) { - struct ref_filter_cbdata ref_cbdata; - int save_commit_buffer_orig; int ret = 0; - ref_cbdata.array = array; - ref_cbdata.filter = filter; - filter->kind = type & FILTER_REFS_KIND_MASK; - save_commit_buffer_orig = save_commit_buffer; - save_commit_buffer = 0; - init_contains_cache(&filter->internal.contains_cache); init_contains_cache(&filter->internal.no_contains_cache); @@ -3001,20 +3001,43 @@ int filter_refs(struct ref_array *array, struct ref_filter *filter, unsigned int * of filter_ref_kind(). */ if (filter->kind == FILTER_REFS_BRANCHES) - ret = for_each_fullref_in("refs/heads/", filter_one, &ref_cbdata); + ret = for_each_fullref_in("refs/heads/", fn, cb_data); else if (filter->kind == FILTER_REFS_REMOTES) - ret = for_each_fullref_in("refs/remotes/", filter_one, &ref_cbdata); + ret = for_each_fullref_in("refs/remotes/", fn, cb_data); else if (filter->kind == FILTER_REFS_TAGS) - ret = for_each_fullref_in("refs/tags/", filter_one, &ref_cbdata); + ret = for_each_fullref_in("refs/tags/", fn, cb_data); else if (filter->kind & FILTER_REFS_ALL) - ret = for_each_fullref_in_pattern(filter, filter_one, &ref_cbdata); + ret = for_each_fullref_in_pattern(filter, fn, cb_data); if (!ret && (filter->kind & FILTER_REFS_DETACHED_HEAD)) - head_ref(filter_one, &ref_cbdata); + head_ref(fn, cb_data); } clear_contains_cache(&filter->internal.contains_cache); clear_contains_cache(&filter->internal.no_contains_cache); + return ret; +} + +/* + * API for filtering a set of refs. Based on the type of refs the user + * has requested, we iterate through those refs and apply filters + * as per the given ref_filter structure and finally store the + * filtered refs in the ref_array structure. + */ +int filter_refs(struct ref_array *array, struct ref_filter *filter, unsigned int type) +{ + struct ref_filter_cbdata ref_cbdata; + int save_commit_buffer_orig; + int ret = 0; + + ref_cbdata.array = array; + ref_cbdata.filter = filter; + + save_commit_buffer_orig = save_commit_buffer; + save_commit_buffer = 0; + + ret = do_filter_refs(filter, type, filter_one, &ref_cbdata); + /* Filters that need revision walking */ reach_filter(array, &filter->reachable_from, INCLUDE_REACHED); reach_filter(array, &filter->unreachable_from, EXCLUDE_REACHED); From patchwork Tue Nov 14 19:53:55 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victoria Dye X-Patchwork-Id: 13455828 Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 92F732FC47 for ; Tue, 14 Nov 2023 19:54:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="By19hHLM" Received: from mail-qt1-x82e.google.com (mail-qt1-x82e.google.com [IPv6:2607:f8b0:4864:20::82e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F3BD2102 for ; Tue, 14 Nov 2023 11:54:15 -0800 (PST) Received: by mail-qt1-x82e.google.com with SMTP id d75a77b69052e-41cd6e1d4fbso35150351cf.1 for ; Tue, 14 Nov 2023 11:54:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1699991654; x=1700596454; darn=vger.kernel.org; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:from:to:cc:subject:date :message-id:reply-to; bh=5XWd6sHPmyhluF5tAor/FSeqnyNOadFnP2v9XS/SCks=; b=By19hHLMlbwX0Vnxx9FSPDxfDyWOpaMTvvEuF5XIoUV2XJZ2F+GDYLp9H6XrZhmIFY 8EKNEEeWh8awYZcefHtxAXtMmX6JBV+0q4OSR7xskfaMocpXjWHaofT2EWiBUvbboNv/ 2p+vTvO4sPfCHw0K6kdhxK6z69nPXm99G1oNnW3TYz9T2y7SvpzzsoE90GbapDFxqQy6 lfz7of39VeQIuBrxChOLb4PoPtl+fRcOJHvWAkb0dB4+r7C6Y/KPnWQ2iUa3IA275/yo DeGK3adEZyPc5Rpr23rP92V8H2cTcYb2Me8n6PdXTG+qy9MKRIB8h6L9FyQzjkATKQMe pTwg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1699991654; x=1700596454; 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 :subject:date:message-id:reply-to; bh=5XWd6sHPmyhluF5tAor/FSeqnyNOadFnP2v9XS/SCks=; b=Jdxi9prbnZOK2amWIHP+j6KdGueDBuxnZvsVMaG4Ff/JLCCSjPcmy/+BrS4TPkggzL 6LpQvhmaIMDe43VyA/EDJL9ST5Z1hY1fRkzz8IXA5EsWYgmEP8AYxK7k6MTI4GXG/boA eNJITo8pFndys8P3z12RHAy0UV0NJjfqJLLONf+aa+sahfgEerBFWa/AXraVkJ9THsCT 13nmp/nGgx/p7p2M+2ABYN+uLSqucw5SwtTOPeiCqYp5kPC5lIwKXTIREujrmlBXbMjQ 2nJBfqsdWVVKZmfuyitbsfHUmwYS9ftCbUQiMTYpXZ8VJCxQWO9+t/dszs9x41zunB6t rEjQ== X-Gm-Message-State: AOJu0YwHz1GN7rcMN4ty/TF1isdlPFMwUohXiAxe9Q12EQAh2w+orWyI tv/3vf/GSdfuuwwikE7NDUQ4JT5u1I8= X-Google-Smtp-Source: AGHT+IHjvOaheHBmUTTdvmxARmEq5gZH+dDOaHFNwLGbyPTZQeB51Py+Jf51albUTwADckpAwkawAQ== X-Received: by 2002:a05:622a:1d6:b0:419:5b97:2fbb with SMTP id t22-20020a05622a01d600b004195b972fbbmr3398829qtw.34.1699991654380; Tue, 14 Nov 2023 11:54:14 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id t19-20020ac865d3000000b0041ce9ebaad2sm2981304qto.43.2023.11.14.11.54.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 14 Nov 2023 11:54:14 -0800 (PST) Message-ID: <91a77c1a834cfc2fbe0676222135c2beb6ed3e01.1699991638.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Tue, 14 Nov 2023 19:53:55 +0000 Subject: [PATCH v2 07/10] ref-filter.c: filter & format refs in the same callback Fcc: Sent Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 To: git@vger.kernel.org Cc: Patrick Steinhardt , =?utf-8?q?=C3=98ystein?= Walle , Kristoffer Haugsbakk , Victoria Dye , Victoria Dye From: Victoria Dye From: Victoria Dye Update 'filter_and_format_refs()' to try to perform ref filtering & formatting in a single ref iteration, without an intermediate 'struct ref_array'. This can only be done if no operations need to be performed on a pre-filtered array; specifically, if the refs are - filtered on reachability, - sorted, or - formatted with ahead-behind information they cannot be filtered & formatted in the same iteration. In that case, fall back on the current filter-then-sort-then-format flow. This optimization substantially improves memory usage due to no longer storing a ref array in memory. In some cases, it also dramatically reduces runtime (e.g. 'git for-each-ref --no-sort --count=1', which no longer loads all refs into a 'struct ref_array' to printing only the first ref). Signed-off-by: Victoria Dye --- ref-filter.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 82 insertions(+), 6 deletions(-) diff --git a/ref-filter.c b/ref-filter.c index ff00ab4b8d8..48453db24f7 100644 --- a/ref-filter.c +++ b/ref-filter.c @@ -2863,6 +2863,49 @@ static void free_array_item(struct ref_array_item *item) free(item); } +struct ref_filter_and_format_cbdata { + struct ref_filter *filter; + struct ref_format *format; + + struct ref_filter_and_format_internal { + int count; + } internal; +}; + +static int filter_and_format_one(const char *refname, const struct object_id *oid, int flag, void *cb_data) +{ + struct ref_filter_and_format_cbdata *ref_cbdata = cb_data; + struct ref_array_item *ref; + struct strbuf output = STRBUF_INIT, err = STRBUF_INIT; + + ref = apply_ref_filter(refname, oid, flag, ref_cbdata->filter); + if (!ref) + return 0; + + if (format_ref_array_item(ref, ref_cbdata->format, &output, &err)) + die("%s", err.buf); + + if (output.len || !ref_cbdata->format->array_opts.omit_empty) { + fwrite(output.buf, 1, output.len, stdout); + putchar('\n'); + } + + strbuf_release(&output); + strbuf_release(&err); + free_array_item(ref); + + /* + * Increment the running count of refs that match the filter. If + * max_count is set and we've reached the max, stop the ref + * iteration by returning a nonzero value. + */ + if (ref_cbdata->format->array_opts.max_count && + ++ref_cbdata->internal.count >= ref_cbdata->format->array_opts.max_count) + return 1; + + return 0; +} + /* Free all memory allocated for ref_array */ void ref_array_clear(struct ref_array *array) { @@ -3046,16 +3089,49 @@ int filter_refs(struct ref_array *array, struct ref_filter *filter, unsigned int return ret; } +static inline int can_do_iterative_format(struct ref_filter *filter, + struct ref_sorting *sorting, + struct ref_format *format) +{ + /* + * Filtering & formatting results within a single ref iteration + * callback is not compatible with options that require + * post-processing a filtered ref_array. These include: + * - filtering on reachability + * - sorting the filtered results + * - including ahead-behind information in the formatted output + */ + return !(filter->reachable_from || + filter->unreachable_from || + sorting || + format->bases.nr); +} + void filter_and_format_refs(struct ref_filter *filter, unsigned int type, struct ref_sorting *sorting, struct ref_format *format) { - struct ref_array array = { 0 }; - filter_refs(&array, filter, type); - filter_ahead_behind(the_repository, format, &array); - ref_array_sort(sorting, &array); - print_formatted_ref_array(&array, format); - ref_array_clear(&array); + if (can_do_iterative_format(filter, sorting, format)) { + int save_commit_buffer_orig; + struct ref_filter_and_format_cbdata ref_cbdata = { + .filter = filter, + .format = format, + }; + + save_commit_buffer_orig = save_commit_buffer; + save_commit_buffer = 0; + + do_filter_refs(filter, type, filter_and_format_one, &ref_cbdata); + + save_commit_buffer = save_commit_buffer_orig; + } else { + struct ref_array array = { 0 }; + filter_refs(&array, filter, type); + filter_ahead_behind(the_repository, format, &array); + ref_array_sort(sorting, &array); + print_formatted_ref_array(&array, format); + ref_array_clear(&array); + } } static int compare_detached_head(struct ref_array_item *a, struct ref_array_item *b) From patchwork Tue Nov 14 19:53:56 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victoria Dye X-Patchwork-Id: 13455829 Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2A1DE2FC3F for ; Tue, 14 Nov 2023 19:54:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="SI1Jso4M" Received: from mail-qk1-x72f.google.com (mail-qk1-x72f.google.com [IPv6:2607:f8b0:4864:20::72f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C8486E6 for ; Tue, 14 Nov 2023 11:54:17 -0800 (PST) Received: by mail-qk1-x72f.google.com with SMTP id af79cd13be357-7788f727dd7so365942685a.1 for ; Tue, 14 Nov 2023 11:54:17 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1699991656; x=1700596456; darn=vger.kernel.org; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:from:to:cc:subject:date :message-id:reply-to; bh=FuSjzb8ICb5KOgTYkuCmKFUpHwEa+zamEtcXoSEXEG0=; b=SI1Jso4MAKsIAXyI2tGBIYtPIPQJf4Uusoed2Sz1p4kWEOqw9fd0PJT1mdOwdyncRp w8m9hWx/bMvv1Q9M0QvA0scoBgKLMDDHUbJ17jn126k9GllCypQJKmReX7eFdqfrqgG2 6mJsto6UNtEt1OJYTH9L9j3M/szVmb/HrBSEASZhMqgXWEo2M9Z0vrXZtQdU2umIh3ZX f/7LYjkgMlJZ1mROboEMuTujczCnCkGkQ8D3Yc1T5kl1JHHp7xT1+PYFS7TygJkKfi03 LsocTnJ9wwHHCb6qHdhAt5M+z7kmjmhQSIpmzBHMfWslnDF3PzflWnj4TZDHRZxP5URV z0lA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1699991656; x=1700596456; 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 :subject:date:message-id:reply-to; bh=FuSjzb8ICb5KOgTYkuCmKFUpHwEa+zamEtcXoSEXEG0=; b=TyuvTnb1M6G8UlAHFJ0CA5dmptw3fgybDQbajtwdekeky+AtmmlGGHUI085fK30B3i irr2Ey0syMsL0m8T+W2zGQk2d/WDf8UXcE8dfResVhLYk8TjAvLBv5UWyqklDw0j5TAe fGhiIPST52oa0DChjhlW6B6wPyAgEBuaEzGXkNC6pMMmU2iufTDePYQFYpoExjHmBlKN 1O8pZNN0A0Bw/I/Vknv9HULOunr/ZyD5nzng96fO/OtXQskwBKuIGhJRJqzZeNnJDALQ sixK4zDuIZWrqlUQGBHAuvcWg9e0AJjkL8rW44kN+VJstPuS8AZ1cSy80I0OedIx/mlX GBGQ== X-Gm-Message-State: AOJu0YwhTLIyizPTH16pIEYW19NV2Zk7MmBMss4Zifl/w+y+rQoMwVtf +2ALN/WiioZrToRtb3xCYSKZtdwBnTM= X-Google-Smtp-Source: AGHT+IHsROCN6ykgVuO67/hMMQ5H47MyrlYzbFNWv6aHYPDSMNYqJzSe+0JGVAWxO6cj88TAXJJ3Wg== X-Received: by 2002:a05:6214:564b:b0:671:ab5c:d14a with SMTP id mh11-20020a056214564b00b00671ab5cd14amr3429861qvb.52.1699991656195; Tue, 14 Nov 2023 11:54:16 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id dw8-20020a0562140a0800b006715ebb014fsm3159752qvb.36.2023.11.14.11.54.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 14 Nov 2023 11:54:15 -0800 (PST) Message-ID: <8eb2fc2950c04bd6fe91112e7056dedeec774e6a.1699991638.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Tue, 14 Nov 2023 19:53:56 +0000 Subject: [PATCH v2 08/10] for-each-ref: clean up documentation of --format Fcc: Sent Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 To: git@vger.kernel.org Cc: Patrick Steinhardt , =?utf-8?q?=C3=98ystein?= Walle , Kristoffer Haugsbakk , Victoria Dye , Victoria Dye From: Victoria Dye From: Victoria Dye Move the description of the `*` prefix from the --format option documentation to the part of the command documentation that deals with other object type-specific modifiers. Also reorganize and reword the remaining --format documentation so that the explanation of the default format doesn't interrupt the details on format string interpolation. Signed-off-by: Victoria Dye --- Documentation/git-for-each-ref.txt | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/Documentation/git-for-each-ref.txt b/Documentation/git-for-each-ref.txt index e86d5700ddf..b136c9fa908 100644 --- a/Documentation/git-for-each-ref.txt +++ b/Documentation/git-for-each-ref.txt @@ -51,17 +51,14 @@ OPTIONS key. --format=:: - A string that interpolates `%(fieldname)` from a ref being shown - and the object it points at. If `fieldname` - is prefixed with an asterisk (`*`) and the ref points - at a tag object, use the value for the field in the object - which the tag object refers to (instead of the field in the tag object). - When unspecified, `` defaults to - `%(objectname) SPC %(objecttype) TAB %(refname)`. - It also interpolates `%%` to `%`, and `%xx` where `xx` - are hex digits interpolates to character with hex code - `xx`; for example `%00` interpolates to `\0` (NUL), - `%09` to `\t` (TAB) and `%0a` to `\n` (LF). + A string that interpolates `%(fieldname)` from a ref being shown and + the object it points at. In addition, the string literal `%%` + renders as `%` and `%xx` - where `xx` are hex digits - renders as + the character with hex code `xx`. For example, `%00` interpolates to + `\0` (NUL), `%09` to `\t` (TAB), and `%0a` to `\n` (LF). ++ +When unspecified, `` defaults to `%(objectname) SPC %(objecttype) +TAB %(refname)`. --color[=]:: Respect any colors specified in the `--format` option. The @@ -298,6 +295,10 @@ fields will correspond to the appropriate date or name-email-date tuple from the `committer` or `tagger` fields depending on the object type. These are intended for working on a mix of annotated and lightweight tags. +For tag objects, a `fieldname` prefixed with an asterisk (`*`) expands to +the `fieldname` value of object the tag points at, rather than that of the +tag object itself. + Fields that have name-email-date tuple as its value (`author`, `committer`, and `tagger`) can be suffixed with `name`, `email`, and `date` to extract the named component. For email fields (`authoremail`, From patchwork Tue Nov 14 19:53:57 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victoria Dye X-Patchwork-Id: 13455830 Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4B0F93D3B4 for ; Tue, 14 Nov 2023 19:54:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="dI951NGy" Received: from mail-qt1-x831.google.com (mail-qt1-x831.google.com [IPv6:2607:f8b0:4864:20::831]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AD0D7102 for ; Tue, 14 Nov 2023 11:54:19 -0800 (PST) Received: by mail-qt1-x831.google.com with SMTP id d75a77b69052e-41b7fd8f458so36736201cf.0 for ; Tue, 14 Nov 2023 11:54:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1699991658; x=1700596458; darn=vger.kernel.org; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:from:to:cc:subject:date :message-id:reply-to; bh=h67uBtDj9QixuqFNHn6CByXAvsoJ40i70Ttc3Pco2u8=; b=dI951NGy5hn6/4Tr+DBerPJ0nuvvSB6/bbTZzic9FUpcL75Db8djD49LU5rJTI/f7g 645xzTO+rNdhqmmJsb+tiyjiKILjh04smLzdhqMh4qZZSTTKhrEF+vFP2ab5gJiLTxVF OD9chS/UsSKJHvgRGzmLQnNDQ2ZztUMOi0yOoIL6NxL/MP/rkZCPvBIy9esULLldbLFc vmiFEpM/1Fj9GyMjcup2VKzPGQYW4J8HpDPRIRUOPsYX7nsShWHlbnefaZ6Hz3xGWCaz pVBas6RAJPRizPpHuD9GchzfVp0TYboTuU3d3cT5sE7sx9LVCw25S1uBWgUj/7m33AMT qKpw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1699991658; x=1700596458; 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 :subject:date:message-id:reply-to; bh=h67uBtDj9QixuqFNHn6CByXAvsoJ40i70Ttc3Pco2u8=; b=givBt9bkKDLYI2elfVN3kcANeL1OS1fQZLXNQSzzgx1trHRlFD+BSOtbvFjr4huF2i dJMKVuuGBBh6XXQPbmydZBs+Fw9Ufgves33ZyF2g6HxzoBSxYS88MZ+8nGUQcHnPpi2S mtYlXLrGtfnzuuhRfxZxRzMzOqT6hNLPwcRAiqbyd9Rx01HjXei3XdJtfMNvhFQullS1 lQLu/x/scQIx2dfhpsfqL8fpQ3T6eCfutBRtI1ElC97f83pJfkwjpcZA1tTwMXJEB2pA R5Zk9L4UyrZd7syt2MBzjfK+HNRGZ0kRmPSonbb5ftetrOgVsv9KCiUFmvd3LQKSlgiB dTOg== X-Gm-Message-State: AOJu0YybIuHO0lUlZif2e+0AKwXT8MWZX3l9IBP4Gij5sqYNsMv/9vfA /AeGQce+YkKHiOZ+lhn34mzF2AJXh5A= X-Google-Smtp-Source: AGHT+IGspugj30OGP0JkrVCxufsf2P32HgWQO4XspN+zhdoAmMWa7PyjXuTUmj3csyg/wtkD5lQocA== X-Received: by 2002:ac8:4e52:0:b0:417:9c40:c606 with SMTP id e18-20020ac84e52000000b004179c40c606mr4413656qtw.4.1699991658090; Tue, 14 Nov 2023 11:54:18 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id t19-20020ac865d3000000b0041ce9ebaad2sm2981367qto.43.2023.11.14.11.54.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 14 Nov 2023 11:54:17 -0800 (PST) Message-ID: <48254d8e161de7f0e165510c06801195f9b0a8fd.1699991638.git.gitgitgadget@gmail.com> In-Reply-To: References: Date: Tue, 14 Nov 2023 19:53:57 +0000 Subject: [PATCH v2 09/10] ref-filter.c: use peeled tag for '*' format fields Fcc: Sent Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 To: git@vger.kernel.org Cc: Patrick Steinhardt , =?utf-8?q?=C3=98ystein?= Walle , Kristoffer Haugsbakk , Victoria Dye , Victoria Dye From: Victoria Dye From: Victoria Dye In most builtins ('rev-parse ^{}', 'show-ref --dereference'), "dereferencing" a tag refers to a recursive peel of the tag object. Unlike these cases, the dereferencing prefix ('*') in 'for-each-ref' format specifiers triggers only a single, non-recursive dereference of a given tag object. For most annotated tags, a single dereference is all that is needed to access the tag's associated commit or tree; "recursive" and "non-recursive" dereferencing are functionally equivalent in these cases. However, nested tags (annotated tags whose target is another annotated tag) dereferenced once return another tag, where a recursive dereference would return the commit or tree. Currently, if a user wants to filter & format refs and include information about a recursively-dereferenced tag, they can do so with something like 'cat-file --batch-check': git for-each-ref --format="%(objectname)^{} %(refname)" | git cat-file --batch-check="%(objectname) %(rest)" But the combination of commands is inefficient. So, to improve the performance of this use case and align the defererencing behavior of 'for-each-ref' with that of other commands, update the ref formatting code to use the peeled tag (from 'peel_iterated_oid()') to populate '*' fields rather than the tag's immediate target object (from 'get_tagged_oid()'). Additionally, add a test to 't6300-for-each-ref' to verify new nested tag behavior and update 't6302-for-each-ref-filter.sh' to print the correct value for nested dereferenced fields. Signed-off-by: Victoria Dye --- Documentation/git-for-each-ref.txt | 4 ++-- ref-filter.c | 13 ++++--------- t/t6300-for-each-ref.sh | 22 ++++++++++++++++++++++ t/t6302-for-each-ref-filter.sh | 4 ++-- 4 files changed, 30 insertions(+), 13 deletions(-) diff --git a/Documentation/git-for-each-ref.txt b/Documentation/git-for-each-ref.txt index b136c9fa908..be9543f6840 100644 --- a/Documentation/git-for-each-ref.txt +++ b/Documentation/git-for-each-ref.txt @@ -296,8 +296,8 @@ from the `committer` or `tagger` fields depending on the object type. These are intended for working on a mix of annotated and lightweight tags. For tag objects, a `fieldname` prefixed with an asterisk (`*`) expands to -the `fieldname` value of object the tag points at, rather than that of the -tag object itself. +the `fieldname` value of the peeled object, rather than that of the tag +object itself. Fields that have name-email-date tuple as its value (`author`, `committer`, and `tagger`) can be suffixed with `name`, `email`, diff --git a/ref-filter.c b/ref-filter.c index 48453db24f7..fdaabb5bb45 100644 --- a/ref-filter.c +++ b/ref-filter.c @@ -2508,17 +2508,12 @@ static int populate_value(struct ref_array_item *ref, struct strbuf *err) return 0; /* - * If it is a tag object, see if we use a value that derefs - * the object, and if we do grab the object it refers to. + * If it is a tag object, see if we use the peeled value. If we do, + * grab the peeled OID. */ - oi_deref.oid = *get_tagged_oid((struct tag *)obj); + if (need_tagged && peel_iterated_oid(&obj->oid, &oi_deref.oid)) + die("bad tag"); - /* - * NEEDSWORK: This derefs tag only once, which - * is good to deal with chains of trust, but - * is not consistent with what deref_tag() does - * which peels the onion to the core. - */ return get_object(ref, 1, &obj, &oi_deref, err); } diff --git a/t/t6300-for-each-ref.sh b/t/t6300-for-each-ref.sh index 0613e5e3623..54e22812598 100755 --- a/t/t6300-for-each-ref.sh +++ b/t/t6300-for-each-ref.sh @@ -1839,6 +1839,28 @@ test_expect_success 'git for-each-ref with non-existing refs' ' test_must_be_empty actual ' +test_expect_success 'git for-each-ref with nested tags' ' + git tag -am "Normal tag" nested/base HEAD && + git tag -am "Nested tag" nested/nest1 refs/tags/nested/base && + git tag -am "Double nested tag" nested/nest2 refs/tags/nested/nest1 && + + head_oid="$(git rev-parse HEAD)" && + base_tag_oid="$(git rev-parse refs/tags/nested/base)" && + nest1_tag_oid="$(git rev-parse refs/tags/nested/nest1)" && + nest2_tag_oid="$(git rev-parse refs/tags/nested/nest2)" && + + cat >expect <<-EOF && + refs/tags/nested/base $base_tag_oid tag $head_oid commit + refs/tags/nested/nest1 $nest1_tag_oid tag $head_oid commit + refs/tags/nested/nest2 $nest2_tag_oid tag $head_oid commit + EOF + + git for-each-ref \ + --format="%(refname) %(objectname) %(objecttype) %(*objectname) %(*objecttype)" \ + refs/tags/nested/ >actual && + test_cmp expect actual +' + GRADE_FORMAT="%(signature:grade)%0a%(signature:key)%0a%(signature:signer)%0a%(signature:fingerprint)%0a%(signature:primarykeyfingerprint)" TRUSTLEVEL_FORMAT="%(signature:trustlevel)%0a%(signature:key)%0a%(signature:signer)%0a%(signature:fingerprint)%0a%(signature:primarykeyfingerprint)" diff --git a/t/t6302-for-each-ref-filter.sh b/t/t6302-for-each-ref-filter.sh index af223e44d67..82f3d1ea0f2 100755 --- a/t/t6302-for-each-ref-filter.sh +++ b/t/t6302-for-each-ref-filter.sh @@ -45,8 +45,8 @@ test_expect_success 'check signed tags with --points-at' ' sed -e "s/Z$//" >expect <<-\EOF && refs/heads/side Z refs/tags/annotated-tag four - refs/tags/doubly-annotated-tag An annotated tag - refs/tags/doubly-signed-tag A signed tag + refs/tags/doubly-annotated-tag four + refs/tags/doubly-signed-tag four refs/tags/four Z refs/tags/signed-tag four EOF From patchwork Tue Nov 14 19:53:58 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victoria Dye X-Patchwork-Id: 13455831 Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 97066405D9 for ; Tue, 14 Nov 2023 19:54:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="g76iAcPa" Received: from mail-qk1-x735.google.com (mail-qk1-x735.google.com [IPv6:2607:f8b0:4864:20::735]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1ABD3E6 for ; Tue, 14 Nov 2023 11:54:21 -0800 (PST) Received: by mail-qk1-x735.google.com with SMTP id af79cd13be357-7788ebea620so399002485a.3 for ; Tue, 14 Nov 2023 11:54:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1699991660; x=1700596460; darn=vger.kernel.org; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date:from :references:in-reply-to:message-id:from:to:cc:subject:date :message-id:reply-to; bh=dHwgU1XJha+CAGvc+iVk56oHIF3XvEoRrTBB5JP6uCA=; b=g76iAcPaCwZZvaUrxQkPft6ZK1mevMFuTZtEf5H0pC8MC73QYSShJj1+p+jTtcVEIs 97oSfGP18rZYJpqicTmB4GrMbCD+OzCRFezMxxMuEPGzVM8BC4NufUiBF/Yx+Y1SpzBK wObuDTiMuJNW5tv87T68ywcgl0b8jLBGXEkr5BZUNKdImwfbQTeHzy9Jz1Q1JWXxY92A eHX91KoEP8Z/JhvC+ckuVRCTS5sptJgJMNlkIk2shol4xA79froxowRP4QAWDg+2N13q uUzgHogHS26k+UAy8n66H4WTr+p26ZljS2gYfmvpKWalqSuujs46QeO/a6HtVutasEyO EqFw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1699991660; x=1700596460; 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 :subject:date:message-id:reply-to; bh=dHwgU1XJha+CAGvc+iVk56oHIF3XvEoRrTBB5JP6uCA=; b=kfBfVzyVrWl0VpQD2TuklQg8DLSx+DnKxuVwoNzh+n0qH3zDoE52xKknHt4AFdxsUS JGRq0I2uFtavj39nZSjdkM3ZKTe6t9Jjn3aczpKwr93p/a+BkC8SruoFRXrHN5zGXpCE LBGZPRn1qfutx5YubkGoFHMSs5npr/v0TYPyXVLBAq9SoEczZlY0aAaf+b/f3GUOlmLP Cj0rWQDe7iywRAajqLzEnOdg76XYvg2WobIl90WD68q3PGOVDWIcNH4fSuXskZRDFk6p ozMt7nGQFUy9D8h/1wsWYQpMxRnZKdk+AXBrRq3XxN5l/qU18o6DZxJK6qo3v+RwzdR6 C5sw== X-Gm-Message-State: AOJu0YxKUNOydwC3yuWy4gUClBDJjQubIjg0krEdsgkuQSQUYuOHYzMq 3VMGCgnsNaakz+hirD/wfSF9KD6nokc= X-Google-Smtp-Source: AGHT+IF4FsxFqa73peR1IJ5nD5iL6yVeakckA/Y/h8mZRbcMoyD9ciEzyWMXL0/Px1Iaodis8XIS1w== X-Received: by 2002:a05:620a:56a:b0:774:13e:71cd with SMTP id p10-20020a05620a056a00b00774013e71cdmr2577207qkp.56.1699991659946; Tue, 14 Nov 2023 11:54:19 -0800 (PST) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id qq3-20020a05620a38c300b0076d08d5f93asm2898042qkn.60.2023.11.14.11.54.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 14 Nov 2023 11:54:19 -0800 (PST) Message-ID: In-Reply-To: References: Date: Tue, 14 Nov 2023 19:53:58 +0000 Subject: [PATCH v2 10/10] t/perf: add perf tests for for-each-ref Fcc: Sent Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 To: git@vger.kernel.org Cc: Patrick Steinhardt , =?utf-8?q?=C3=98ystein?= Walle , Kristoffer Haugsbakk , Victoria Dye , Victoria Dye From: Victoria Dye From: Victoria Dye Add performance tests for 'for-each-ref'. The tests exercise different combinations of filters/formats/options, as well as the overall performance of 'git for-each-ref | git cat-file --batch-check' to demonstrate the performance difference vs. 'git for-each-ref' with "%(*fieldname)" format specifiers. All tests are run against a repository with 40k loose refs - 10k commits, each having a unique: - branch - custom ref (refs/custom/special_*) - annotated tag pointing at the commit - annotated tag pointing at the other annotated tag (i.e., a nested tag) After those tests are finished, the refs are packed with 'pack-refs --all' and the same tests are rerun. Signed-off-by: Victoria Dye --- t/perf/p6300-for-each-ref.sh | 87 ++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100755 t/perf/p6300-for-each-ref.sh diff --git a/t/perf/p6300-for-each-ref.sh b/t/perf/p6300-for-each-ref.sh new file mode 100755 index 00000000000..fa7289c7522 --- /dev/null +++ b/t/perf/p6300-for-each-ref.sh @@ -0,0 +1,87 @@ +#!/bin/sh + +test_description='performance of for-each-ref' +. ./perf-lib.sh + +test_perf_fresh_repo + +ref_count_per_type=10000 +test_iteration_count=10 + +test_expect_success "setup" ' + test_commit_bulk $(( 1 + $ref_count_per_type )) && + + # Create refs + test_seq $ref_count_per_type | + sed "s,.*,update refs/heads/branch_& HEAD~&\nupdate refs/custom/special_& HEAD~&," | + git update-ref --stdin && + + # Create annotated tags + for i in $(test_seq $ref_count_per_type) + do + # Base tags + echo "tag tag_$i" && + echo "mark :$i" && + echo "from HEAD~$i" && + printf "tagger %s <%s> %s\n" \ + "$GIT_COMMITTER_NAME" \ + "$GIT_COMMITTER_EMAIL" \ + "$GIT_COMMITTER_DATE" && + echo "data < %s\n" \ + "$GIT_COMMITTER_NAME" \ + "$GIT_COMMITTER_EMAIL" \ + "$GIT_COMMITTER_DATE" && + echo "data </dev/null + done + " +} + +run_tests () { + test_for_each_ref "$1" + test_for_each_ref "$1, no sort" --no-sort + test_for_each_ref "$1, --count=1" --count=1 + test_for_each_ref "$1, --count=1, no sort" --no-sort --count=1 + test_for_each_ref "$1, tags" refs/tags/ + test_for_each_ref "$1, tags, no sort" --no-sort refs/tags/ + test_for_each_ref "$1, tags, dereferenced" '--format="%(refname) %(objectname) %(*objectname)"' refs/tags/ + test_for_each_ref "$1, tags, dereferenced, no sort" --no-sort '--format="%(refname) %(objectname) %(*objectname)"' refs/tags/ + + test_perf "for-each-ref ($1, tags) + cat-file --batch-check (dereferenced)" " + for i in \$(test_seq $test_iteration_count); do + git for-each-ref --format='%(objectname)^{} %(refname) %(objectname)' refs/tags/ | \ + git cat-file --batch-check='%(objectname) %(rest)' >/dev/null + done + " +} + +run_tests "loose" + +test_expect_success 'pack refs' ' + git pack-refs --all +' +run_tests "packed" + +test_done