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

Re: [PATCH 1/9] refs/reftable: fix D/F conflict error message on ref copy

From
Junio C Hamano <gitster@pobox.com>
Date
Apr 3, 2024, 18:28 UTC
Message-ID
<xmqqr0fm713f.fsf@gitster.g>
In-Reply-To
<14b4dacd731a7d9c19029cd8a0c3b6170c31ae25.1712078736.git.ps@pks.im>
Patrick Steinhardt <ps@pks.im> writes:
Show 22 quoted lines
> The `write_copy_table()` function is shared between the reftable
> implementations for renaming and copying refs. The only difference
> between those two cases is that the rename will also delete the old
> reference, whereas copying won't.
>
> This has resulted in a bug though where we don't properly verify refname
> availability. When calling `refs_verify_refname_available()`, we always
> add the old ref name to the list of refs to be skipped when computing
> availability, which indicates that the name would be available even if
> it already exists at the current point in time. This is only the right
> thing to do for renames though, not for copies.
>
> The consequence of this bug is quite harmless because the reftable
> backend has its own checks for D/F conflicts further down in the call
> stack, and thus we refuse the update regardless of the bug. But all the
> user gets in this case is an uninformative message that copying the ref
> has failed, without any further details.
>
> Fix the bug and only add the old name to the skip-list in case we rename
> the ref. Consequently, this error case will now be handled by
> `refs_verify_refname_available()`, which knows to provide a proper error
> message.

OK. Nicely described. Instead of letting the reftable code downstream to notice an update that was left uncaught by an extra element in &skip, we will let refs_verify_refname_available() to catch it at the right place. Makes sense.

Show 64 quoted lines
> Signed-off-by: Patrick Steinhardt <ps@pks.im>
> ---
>  refs/reftable-backend.c    |  3 ++-
>  t/t0610-reftable-basics.sh | 33 +++++++++++++++++++++++++++++++++
>  2 files changed, 35 insertions(+), 1 deletion(-)
>
> diff --git a/refs/reftable-backend.c b/refs/reftable-backend.c
> index e206d5a073..0358da14db 100644
> --- a/refs/reftable-backend.c
> +++ b/refs/reftable-backend.c
> @@ -1351,7 +1351,8 @@ static int write_copy_table(struct reftable_writer *writer, void *cb_data)
>  	/*
>  	 * Verify that the new refname is available.
>  	 */
> -	string_list_insert(&skip, arg->oldname);
> +	if (arg->delete_old)
> +		string_list_insert(&skip, arg->oldname);
>  	ret = refs_verify_refname_available(&arg->refs->base, arg->newname,
>  					    NULL, &skip, &errbuf);
>  	if (ret < 0) {
> diff --git a/t/t0610-reftable-basics.sh b/t/t0610-reftable-basics.sh
> index 686781192e..055231a707 100755
> --- a/t/t0610-reftable-basics.sh
> +++ b/t/t0610-reftable-basics.sh
> @@ -730,6 +730,39 @@ test_expect_success 'reflog: updates via HEAD update HEAD reflog' '
>  	)
>  '
>  
> +test_expect_success 'branch: copying branch with D/F conflict' '
> +	test_when_finished "rm -rf repo" &&
> +	git init repo &&
> +	(
> +		cd repo &&
> +		test_commit A &&
> +		git branch branch &&
> +		cat >expect <<-EOF &&
> +		error: ${SQ}refs/heads/branch${SQ} exists; cannot create ${SQ}refs/heads/branch/moved${SQ}
> +		fatal: branch copy failed
> +		EOF
> +		test_must_fail git branch -c branch branch/moved 2>err &&
> +		test_cmp expect err
> +	)
> +'
> +
> +test_expect_success 'branch: moving branch with D/F conflict' '
> +	test_when_finished "rm -rf repo" &&
> +	git init repo &&
> +	(
> +		cd repo &&
> +		test_commit A &&
> +		git branch branch &&
> +		git branch conflict &&
> +		cat >expect <<-EOF &&
> +		error: ${SQ}refs/heads/conflict${SQ} exists; cannot create ${SQ}refs/heads/conflict/moved${SQ}
> +		fatal: branch rename failed
> +		EOF
> +		test_must_fail git branch -m branch conflict/moved 2>err &&
> +		test_cmp expect err
> +	)
> +'
> +
>  test_expect_success 'worktree: adding worktree creates separate stack' '
>  	test_when_finished "rm -rf repo worktree" &&
>  	git init repo &&
Previous: Patrick SteinhardtNext: Patrick Steinhardt
Message 3 of 49 in “reftable: optimize write performance”
  1. 0/9 reftable: optimize write performancePatrick Steinhardt, Apr 2, 2024
  2. 1/9 refs/reftable: fix D/F conflict error message on ref copyPatrick Steinhardt, Apr 2, 2024
  3. Junio C HamanoApr 3, 2024
  4. 2/9 refs/reftable: perform explicit D/F check when writing symrefsPatrick Steinhardt, Apr 2, 2024
  5. 3/9 refs/reftable: skip duplicate name checksPatrick Steinhardt, Apr 2, 2024
  6. 4/9 refs/reftable: don't recompute committer identPatrick Steinhardt, Apr 2, 2024
  7. Junio C HamanoApr 3, 2024
  8. Patrick SteinhardtApr 4, 2024
  9. 5/9 reftable/writer: refactorings for `writer_add_record()`Patrick Steinhardt, Apr 2, 2024
  10. 6/9 reftable/writer: refactorings for `writer_flush_nonempty_block()`Patrick Steinhardt, Apr 2, 2024
  11. 7/9 reftable/block: reuse zstream when writing log blocksPatrick Steinhardt, Apr 2, 2024
  12. Junio C HamanoApr 3, 2024
  13. Patrick SteinhardtApr 4, 2024
  14. 8/9 reftable/block: reuse compressed arrayPatrick Steinhardt, Apr 2, 2024
  15. 9/9 reftable/writer: reset `last_key` instead of releasing itPatrick Steinhardt, Apr 2, 2024
  16. 00/11 reftable: optimize write performancePatrick Steinhardt, Apr 4, 2024
  17. 01/11 refs/reftable: fix D/F conflict error message on ref copyPatrick Steinhardt, Apr 4, 2024
  18. 02/11 refs/reftable: perform explicit D/F check when writing symrefsPatrick Steinhardt, Apr 4, 2024
  19. 03/11 refs/reftable: skip duplicate name checksPatrick Steinhardt, Apr 4, 2024
  20. 04/11 reftable: remove name checksPatrick Steinhardt, Apr 4, 2024
  21. 05/11 refs/reftable: don't recompute committer identPatrick Steinhardt, Apr 4, 2024
  22. 06/11 reftable/writer: refactorings for `writer_add_record()`Patrick Steinhardt, Apr 4, 2024
  23. Han-Wen NienhuysApr 4, 2024
  24. Patrick SteinhardtApr 4, 2024
  25. 07/11 reftable/writer: refactorings for `writer_flush_nonempty_block()`Patrick Steinhardt, Apr 4, 2024
  26. 08/11 reftable/writer: unify releasing memoryPatrick Steinhardt, Apr 4, 2024
  27. Han-Wen NienhuysApr 4, 2024
  28. Patrick SteinhardtApr 4, 2024
  29. Han-Wen NienhuysApr 4, 2024
  30. Patrick SteinhardtApr 4, 2024
  31. 09/11 reftable/writer: reset `last_key` instead of releasing itPatrick Steinhardt, Apr 4, 2024
  32. 10/11 reftable/block: reuse zstream when writing log blocksPatrick Steinhardt, Apr 4, 2024
  33. 11/11 reftable/block: reuse compressed arrayPatrick Steinhardt, Apr 4, 2024
  34. Han-Wen NienhuysApr 4, 2024
  35. Patrick SteinhardtApr 4, 2024
  36. 00/11 reftable: optimize write performancePatrick Steinhardt, Apr 8, 2024
  37. 01/11 refs/reftable: fix D/F conflict error message on ref copyPatrick Steinhardt, Apr 8, 2024
  38. 02/11 refs/reftable: perform explicit D/F check when writing symrefsPatrick Steinhardt, Apr 8, 2024
  39. 03/11 refs/reftable: skip duplicate name checksPatrick Steinhardt, Apr 8, 2024
  40. 04/11 reftable: remove name checksPatrick Steinhardt, Apr 8, 2024
  41. 05/11 refs/reftable: don't recompute committer identPatrick Steinhardt, Apr 8, 2024
  42. 06/11 reftable/writer: refactorings for `writer_add_record()`Patrick Steinhardt, Apr 8, 2024
  43. 07/11 reftable/writer: refactorings for `writer_flush_nonempty_block()`Patrick Steinhardt, Apr 8, 2024
  44. 08/11 reftable/writer: unify releasing memoryPatrick Steinhardt, Apr 8, 2024
  45. 09/11 reftable/writer: reset `last_key` instead of releasing itPatrick Steinhardt, Apr 8, 2024
  46. 10/11 reftable/block: reuse zstream when writing log blocksPatrick Steinhardt, Apr 8, 2024
  47. 11/11 reftable/block: reuse compressed arrayPatrick Steinhardt, Apr 8, 2024
  48. Junio C HamanoApr 9, 2024
  49. Patrick SteinhardtApr 9, 2024

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.