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

Re: [PATCH v2 6/6] refs: skip hooks when deleting uncovered packed refs

From
Junio C Hamano <gitster@pobox.com>
Date
Jan 8, 2022, 02:01 UTC
Message-ID
<xmqq1r1j3s0v.fsf@gitster.g>
In-Reply-To
<0fbf68dbf434986aa971961e20598675b2194d51.1641556319.git.ps@pks.im>
Patrick Steinhardt <ps@pks.im> writes:
Show 14 quoted lines
> When deleting refs from the loose-files refs backend, then we need to be
> careful to also delete the same ref from the packed refs backend, if it
> exists. If we don't, then deleting the loose ref would "uncover" the
> packed ref. We thus always have to queue up deletions of refs for both
> the loose and the packed refs backend. This is done in two separate
> transactions, where the end result is that the reference-transaction
> hook is executed twice for the deleted refs.
>
> This behaviour is quite misleading: it's exposing implementation details
> of how the files backend works to the user, in contrast to the logical
> updates that we'd really want to expose via the hook. Worse yet, whether
> the hook gets executed once or twice depends on how well-packed the
> repository is: if the ref only exists as a loose ref, then we execute it
> once, otherwise if it is also packed then we execute it twice.
If the ref only exists as a packed ref, what happens? ...
> Fix this behaviour and don't execute the reference-transaction hook at
> all when refs in the packed-refs backend if it's driven by the files
> backend.

... We try to remove from the loose backend, which would say "nah, it did not exist in my store". I am not sure if it should execute the delete hook in such a case for the ref. But if it does not, not running the hook in the ref transaction for packed backend driven by the loose backend would mean nobody notifies the deletion of the ref, no?

To me, it seems that the only case this strategy would work correctly is when the files backend calls deletion hook for a request to delete nonexistent ref, which by itself sounds like a problem.

Show 61 quoted lines
> Signed-off-by: Patrick Steinhardt <ps@pks.im>
> ---
>  refs/files-backend.c             | 9 ++++++---
>  t/t1416-ref-transaction-hooks.sh | 7 +------
>  2 files changed, 7 insertions(+), 9 deletions(-)
>
> diff --git a/refs/files-backend.c b/refs/files-backend.c
> index 3c0f3027fe..9a20cb8fa8 100644
> --- a/refs/files-backend.c
> +++ b/refs/files-backend.c
> @@ -1261,7 +1261,8 @@ static int files_delete_refs(struct ref_store *ref_store, const char *msg,
>  	if (packed_refs_lock(refs->packed_ref_store, 0, &err))
>  		goto error;
>  
> -	transaction = ref_store_transaction_begin(refs->packed_ref_store, 0, &err);
> +	transaction = ref_store_transaction_begin(refs->packed_ref_store,
> +						  REF_TRANSACTION_SKIP_HOOK, &err);
>  	if (!transaction)
>  		goto error;
>  
> @@ -2775,7 +2776,8 @@ static int files_transaction_prepare(struct ref_store *ref_store,
>  			 */
>  			if (!packed_transaction) {
>  				packed_transaction = ref_store_transaction_begin(
> -						refs->packed_ref_store, 0, err);
> +						refs->packed_ref_store,
> +						REF_TRANSACTION_SKIP_HOOK, err);
>  				if (!packed_transaction) {
>  					ret = TRANSACTION_GENERIC_ERROR;
>  					goto cleanup;
> @@ -3046,7 +3048,8 @@ static int files_initial_transaction_commit(struct ref_store *ref_store,
>  				 &affected_refnames))
>  		BUG("initial ref transaction called with existing refs");
>  
> -	packed_transaction = ref_store_transaction_begin(refs->packed_ref_store, 0, err);
> +	packed_transaction = ref_store_transaction_begin(refs->packed_ref_store,
> +							 REF_TRANSACTION_SKIP_HOOK, err);
>  	if (!packed_transaction) {
>  		ret = TRANSACTION_GENERIC_ERROR;
>  		goto cleanup;
> diff --git a/t/t1416-ref-transaction-hooks.sh b/t/t1416-ref-transaction-hooks.sh
> index f9d3d5213f..4e1e84a91f 100755
> --- a/t/t1416-ref-transaction-hooks.sh
> +++ b/t/t1416-ref-transaction-hooks.sh
> @@ -175,16 +175,11 @@ test_expect_success 'deleting packed ref calls hook once' '
>  	git update-ref -d refs/heads/to-be-deleted $POST_OID &&
>  
>  	# We only expect a single hook invocation, which is the logical
> -	# deletion. But currently, we see two interleaving transactions, once
> -	# for deleting the loose refs and once for deleting the packed ref.
> +	# deletion.
>  	cat >expect <<-EOF &&
> -		prepared
> -		$ZERO_OID $ZERO_OID refs/heads/to-be-deleted
>  		prepared
>  		$POST_OID $ZERO_OID refs/heads/to-be-deleted
>  		committed
> -		$ZERO_OID $ZERO_OID refs/heads/to-be-deleted
> -		committed
>  		$POST_OID $ZERO_OID refs/heads/to-be-deleted
>  	EOF
Previous: Patrick SteinhardtNext: Patrick Steinhardt
Message 21 of 51 in “refs: excessive hook execution with packed refs”
  1. 0/6 refs: excessive hook execution with packed refsPatrick Steinhardt, Dec 7, 2021
  2. 1/6 refs: open-code deletion of packed refsPatrick Steinhardt, Dec 7, 2021
  3. 2/6 refs: allow passing flags when beginning transactionsPatrick Steinhardt, Dec 7, 2021
  4. 3/6 refs: allow skipping the reference-transaction hookPatrick Steinhardt, Dec 7, 2021
  5. 4/6 refs: demonstrate excessive execution of the reference-transaction hookPatrick Steinhardt, Dec 7, 2021
  6. 5/6 refs: do not execute reference-transaction hook on packing refsPatrick Steinhardt, Dec 7, 2021
  7. 6/6 refs: skip hooks when deleting uncovered packed refsPatrick Steinhardt, Dec 7, 2021
  8. 0/6 refs: excessive hook execution with packed refsPatrick Steinhardt, Jan 7, 2022
  9. 1/6 refs: open-code deletion of packed refsPatrick Steinhardt, Jan 7, 2022
  10. Junio C HamanoJan 8, 2022
  11. Junio C HamanoJan 8, 2022
  12. Junio C HamanoJan 13, 2022
  13. 2/6 refs: allow passing flags when beginning transactionsPatrick Steinhardt, Jan 7, 2022
  14. Junio C HamanoJan 8, 2022
  15. 3/6 refs: allow skipping the reference-transaction hookPatrick Steinhardt, Jan 7, 2022
  16. 4/6 refs: demonstrate excessive execution of the reference-transaction hookPatrick Steinhardt, Jan 7, 2022
  17. Junio C HamanoJan 8, 2022
  18. Patrick SteinhardtJan 10, 2022
  19. Eric SunshineJan 8, 2022
  20. 6/6 refs: skip hooks when deleting uncovered packed refsPatrick Steinhardt, Jan 7, 2022
  21. Junio C HamanoJan 8, 2022
  22. Patrick SteinhardtJan 10, 2022
  23. Junio C HamanoJan 10, 2022
  24. 5/6 refs: do not execute reference-transaction hook on packing refsPatrick Steinhardt, Jan 7, 2022
  25. Junio C HamanoJan 7, 2022
  26. Han-Wen NienhuysJan 13, 2022
  27. Patrick SteinhardtJan 17, 2022
  28. Han-Wen NienhuysJan 17, 2022
  29. Patrick SteinhardtJan 24, 2022
  30. 0/6 refs: excessive hook execution with packed refsPatrick Steinhardt, Jan 13, 2022
  31. 1/6 refs: extract packed_refs_delete_refs() to allow control of transactionPatrick Steinhardt, Jan 13, 2022
  32. Ævar Arnfjörð BjarmasonJan 13, 2022
  33. Patrick SteinhardtJan 17, 2022
  34. 2/6 refs: allow passing flags when beginning transactionsPatrick Steinhardt, Jan 13, 2022
  35. 3/6 refs: allow skipping the reference-transaction hookPatrick Steinhardt, Jan 13, 2022
  36. Ævar Arnfjörð BjarmasonJan 13, 2022
  37. Patrick SteinhardtJan 17, 2022
  38. 4/6 refs: demonstrate excessive execution of the reference-transaction hookPatrick Steinhardt, Jan 13, 2022
  39. 5/6 refs: do not execute reference-transaction hook on packing refsPatrick Steinhardt, Jan 13, 2022
  40. Ævar Arnfjörð BjarmasonJan 13, 2022
  41. Patrick SteinhardtJan 17, 2022
  42. 6/6 refs: skip hooks when deleting uncovered packed refsPatrick Steinhardt, Jan 13, 2022
  43. Ævar Arnfjörð BjarmasonJan 13, 2022
  44. Patrick SteinhardtJan 17, 2022
  45. 0/6 refs: excessive hook execution with packed refsPatrick Steinhardt, Jan 17, 2022
  46. 1/6 refs: extract packed_refs_delete_refs() to allow control of transactionPatrick Steinhardt, Jan 17, 2022
  47. 2/6 refs: allow passing flags when beginning transactionsPatrick Steinhardt, Jan 17, 2022
  48. 3/6 refs: allow skipping the reference-transaction hookPatrick Steinhardt, Jan 17, 2022
  49. 4/6 refs: demonstrate excessive execution of the reference-transaction hookPatrick Steinhardt, Jan 17, 2022
  50. 5/6 refs: do not execute reference-transaction hook on packing refsPatrick Steinhardt, Jan 17, 2022
  51. 6/6 refs: skip hooks when deleting uncovered packed refsPatrick Steinhardt, Jan 17, 2022

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.