git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH 3/5] refspec: output a refspec item

From
Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Date
Apr 7, 2021, 08:46 UTC
Message-ID
<87r1jmjxdg.fsf@evledraar.gmail.com>
In-Reply-To
<e10007e1cf8ff0005295f648b9489c11a9427122.1617627856.git.gitgitgadget@gmail.com>
On Mon, Apr 05 2021, Derrick Stolee via GitGitGadget wrote:
Show 54 quoted lines
> From: Derrick Stolee <dstolee@microsoft.com>
>
> 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 <dstolee@microsoft.com>
> ---
>  refspec.c | 25 +++++++++++++++++++++++++
>  refspec.h |  5 +++++
>  2 files changed, 30 insertions(+)
>
> diff --git a/refspec.c b/refspec.c
> index e3d852c0bfec..ca65ba01bfe6 100644
> --- a/refspec.c
> +++ b/refspec.c
> @@ -180,6 +180,31 @@ void refspec_item_clear(struct refspec_item *item)
>  	item->exact_sha1 = 0;
>  }
>  
> +const char *refspec_item_format(const struct refspec_item *rsi)
> +{
> +	static struct strbuf buf = STRBUF_INIT;
> +
> +	strbuf_reset(&buf);
> +
> +	if (rsi->matching)
> +		return ":";
> +
> +	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 buf.buf;

There's a downthread discussion about the strbuf usage here so that's covered.

But I'm still confused about the need for this function and the
following two patches. If we apply this on top of your series:
    
    diff --git a/t/helper/test-refspec.c b/t/helper/test-refspec.c
    index 08cf441a0a0..9e099e43ebf 100644
    --- a/t/helper/test-refspec.c
    +++ b/t/helper/test-refspec.c
    @@ -31,7 +31,7 @@ int cmd__refspec(int argc, const char **argv)
                            continue;
                    }
    
    -               printf("%s\n", refspec_item_format(&rsi));
    +               puts(line.buf);
                    refspec_item_clear(&rsi);
            }
The only failing test is:
    
    + diff -u expect output
    --- expect      2021-04-07 08:12:05.577598038 +0000
    +++ output      2021-04-07 08:12:05.577598038 +0000
    @@ -11,5 +11,5 @@
     refs/heads*/for-linus:refs/remotes/mine/*
     2e36527f23b7f6ae15e6f21ac3b08bf3fed6ee48:refs/heads/fixed
     HEAD
    -HEAD
    +@
     :
Other than that applying this on top makes everything pass:
    
    diff --git a/builtin/gc.c b/builtin/gc.c
    index 92cb8b4e0bf..ea5572d15c5 100644
    --- a/builtin/gc.c
    +++ b/builtin/gc.c
    @@ -889,35 +889,21 @@ static int fetch_remote(struct remote *remote, void *cbdata)
     		strvec_push(&child.args, "--quiet");
     
     	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;
    +		struct strbuf new_spec = STRBUF_INIT;
    +		char *pos;
     
     		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);
    -
    -		strvec_push(&child.args, refspec_item_format(&replace));
    -
    -		refspec_item_clear(&replace);
    +		strbuf_addstr(&new_spec, remote->fetch.raw[i]);
    +		if ((pos = strrchr(new_spec.buf, ':')) != NULL)
    +			strbuf_splice(&new_spec, pos - new_spec.buf + 1, sizeof("refs/") - 1,
    +				      "refs/prefetch/", sizeof("refs/prefetch/") - 1);
    +		strvec_push(&child.args, new_spec.buf);
    +		strbuf_release(&new_spec);
     	}
     
     	return !!run_command(&child);

So the purpose of this new API is that we don't want to make the assumption that strrchr(buf, ':') is a safe way to find the delimiter in the refspec, or is there some case where we grok "HEAD" but not "@" that's buggy, but not tested for in this series?

Previous: Derrick StoleeNext: Derrick Stolee
Message 14 of 72 in “Maintenance: adapt custom refspecs”
  1. 0/5 Maintenance: adapt custom refspecsDerrick Stolee via GitGitGadget, Apr 5, 2021
  2. 2/5 test-lib: use exact match for test_subcommandDerrick Stolee via GitGitGadget, Apr 5, 2021
  3. Eric SunshineApr 5, 2021
  4. Junio C HamanoApr 5, 2021
  5. 1/5 maintenance: simplify prefetch logicDerrick Stolee via GitGitGadget, Apr 5, 2021
  6. Tom SaegerApr 5, 2021
  7. 3/5 refspec: output a refspec itemDerrick Stolee via GitGitGadget, Apr 5, 2021
  8. Tom SaegerApr 5, 2021
  9. Eric SunshineApr 5, 2021
  10. Junio C HamanoApr 5, 2021
  11. Derrick StoleeApr 6, 2021
  12. Eric SunshineApr 6, 2021
  13. Derrick StoleeApr 6, 2021
  14. Ævar Arnfjörð BjarmasonApr 7, 2021
  15. Derrick StoleeApr 7, 2021
  16. Ævar Arnfjörð BjarmasonApr 7, 2021
  17. Junio C HamanoApr 7, 2021
  18. Ævar Arnfjörð BjarmasonApr 7, 2021
  19. Junio C HamanoApr 8, 2021
  20. 4/5 test-tool: test refspec input/outputDerrick Stolee via GitGitGadget, Apr 5, 2021
  21. Eric SunshineApr 5, 2021
  22. Derrick StoleeApr 6, 2021
  23. Ævar Arnfjörð BjarmasonApr 7, 2021
  24. 5/5 maintenance: allow custom refspecs during prefetchDerrick Stolee via GitGitGadget, Apr 5, 2021
  25. Tom SaegerApr 5, 2021
  26. Derrick StoleeApr 6, 2021
  27. Ævar Arnfjörð BjarmasonApr 7, 2021
  28. Ævar Arnfjörð BjarmasonApr 7, 2021
  29. Derrick StoleeApr 9, 2021
  30. Ævar Arnfjörð BjarmasonApr 9, 2021
  31. Derrick StoleeApr 10, 2021
  32. Ævar Arnfjörð BjarmasonApr 10, 2021
  33. Ævar Arnfjörð BjarmasonApr 7, 2021
  34. 0/5 Maintenance: adapt custom refspecsDerrick Stolee via GitGitGadget, Apr 6, 2021
  35. 1/5 maintenance: simplify prefetch logicDerrick Stolee via GitGitGadget, Apr 6, 2021
  36. Emily ShafferApr 7, 2021
  37. Derrick StoleeApr 9, 2021
  38. 2/5 test-lib: use exact match for test_subcommandDerrick Stolee via GitGitGadget, Apr 6, 2021
  39. 4/5 test-tool: test refspec input/outputDerrick Stolee via GitGitGadget, Apr 6, 2021
  40. Josh SteadmonApr 7, 2021
  41. Emily ShafferApr 7, 2021
  42. 3/5 refspec: output a refspec itemDerrick Stolee via GitGitGadget, Apr 6, 2021
  43. 5/5 maintenance: allow custom refspecs during prefetchDerrick Stolee via GitGitGadget, Apr 6, 2021
  44. Tom SaegerApr 6, 2021
  45. Derrick StoleeApr 6, 2021
  46. Josh SteadmonApr 7, 2021
  47. Emily ShafferApr 7, 2021
  48. Jonathan TanApr 8, 2021
  49. 0/3 Maintenance: adapt custom refspecsDerrick Stolee via GitGitGadget, Apr 10, 2021
  50. 2/3 fetch: add --prefetch optionDerrick Stolee via GitGitGadget, Apr 10, 2021
  51. Ramsay JonesApr 11, 2021
  52. Derrick StoleeApr 12, 2021
  53. 3/3 maintenance: use 'git fetch --prefetch'Derrick Stolee via GitGitGadget, Apr 10, 2021
  54. 1/3 maintenance: simplify prefetch logicDerrick Stolee via GitGitGadget, Apr 10, 2021
  55. Tom SaegerApr 12, 2021
  56. Derrick StoleeApr 12, 2021
  57. Junio C HamanoApr 11, 2021
  58. Tom SaegerApr 12, 2021
  59. Tom SaegerApr 12, 2021
  60. Tom SaegerApr 12, 2021
  61. Derrick StoleeApr 12, 2021
  62. 0/4 Maintenance: adapt custom refspecsDerrick Stolee via GitGitGadget, Apr 16, 2021
  63. 1/4 maintenance: simplify prefetch logicDerrick Stolee via GitGitGadget, Apr 16, 2021
  64. Tom SaegerApr 16, 2021
  65. 2/4 fetch: add --prefetch optionDerrick Stolee via GitGitGadget, Apr 16, 2021
  66. Tom SaegerApr 16, 2021
  67. Tom SaegerApr 16, 2021
  68. 3/4 maintenance: use 'git fetch --prefetch'Derrick Stolee via GitGitGadget, Apr 16, 2021
  69. 4/4 maintenance: respect remote.*.skipFetchAllDerrick Stolee via GitGitGadget, Apr 16, 2021
  70. Ævar Arnfjörð BjarmasonApr 16, 2021
  71. Tom SaegerApr 16, 2021
  72. Tom SaegerApr 16, 2021

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.