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

Re: [PATCH 15/29] ref_transaction_create(): disallow recursive pruning

From
Junio C Hamano <gitster@pobox.com>
Date
Apr 28, 2016, 20:15 UTC
Message-ID
<xmqq60v14hhx.fsf@gitster.mtv.corp.google.com>
In-Reply-To
<1461865718.4123.4.camel@twopensource.com>
David Turner <dturner@twopensource.com> writes:
> Since there is a manual check for that case, the code will fail at test
> time.

I see a difference between "We make it hard to write incorrect code" and "We keep it easy to write incorrect code but a runtime check will catch mistakes anyway", and I tend to prefer the former.

I do think the "manual check" needs to be kept in an adjusted form even if we decide to take the suggested update. A caller can pass 0x04 instead of REF_ISPRUNING after all---but that is exactly the case where you have to work hard to write incorrect code.

One existing check that is not touched with 15/29 also needs to be adjusted. An incremental update relative to 15/29 would look like this:

 refs.c               | 4 ++--
 refs/files-backend.c | 4 ++--
 refs/refs-internal.h | 6 ++++--
 3 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/refs.c b/refs.c
index 5dc2473..bb81dfd 100644
--- a/refs.c
+++ b/refs.c
@@ -790,8 +790,8 @@ int ref_transaction_update(struct ref_transaction *transaction,
 	if (transaction->state != REF_TRANSACTION_OPEN)
 		die("BUG: update called for transaction that is not open");
 
-	if ((flags & REF_ISPRUNING) && !(flags & REF_NODEREF))
-		die("BUG: REF_ISPRUNING set without REF_NODEREF");
+	if ((flags & REF_ISPRUNING_) && !(flags & REF_NODEREF))
+		die("BUG: REF_ISPRUNING_ set without REF_NODEREF");
 
 	if (new_sha1 && !is_null_sha1(new_sha1) &&
 	    check_refname_format(refname, REFNAME_ALLOW_ONELEVEL)) {
diff --git a/refs/files-backend.c b/refs/files-backend.c
index 8fcbd7d..012e3d0 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -2116,7 +2116,7 @@ static void prune_ref(struct ref_to_prune *r)
 	transaction = ref_transaction_begin(&err);
 	if (!transaction ||
 	    ref_transaction_delete(transaction, r->name, r->sha1,
-				   REF_ISPRUNING | REF_NODEREF, NULL, &err) ||
+				   REF_ISPRUNING, NULL, &err) ||
 	    ref_transaction_commit(transaction, &err)) {
 		ref_transaction_free(transaction);
 		error("%s", err.buf);
@@ -3178,7 +3178,7 @@ int ref_transaction_commit(struct ref_transaction *transaction,
 				goto cleanup;
 			}
 
-			if (!(update->flags & REF_ISPRUNING))
+			if (!(update->flags & REF_ISPRUNING_))
 				string_list_append(&refs_to_delete,
 						   update->lock->ref_name);
 		}
diff --git a/refs/refs-internal.h b/refs/refs-internal.h
index 37a1a37..0a2bf1f 100644
--- a/refs/refs-internal.h
+++ b/refs/refs-internal.h
@@ -15,9 +15,11 @@
 
 /*
  * Used as a flag in ref_update::flags when a loose ref is being
- * pruned.
+ * pruned.  As this must always be done with REF_NODEREF, we make
+ * the public version REF_ISPRUNING to contain REF_NODEREF.
  */
-#define REF_ISPRUNING	0x04
+#define REF_ISPRUNING_	0x04
+#define REF_ISPRUNING	(REF_ISPRUNING_ | REF_NODEREF)
 
 /*
  * Used as a flag in ref_update::flags when the reference should be
Previous: David TurnerNext: Michael Haggerty
Message 32 of 70 in “Yet more preparation for reference backends”
  1. 00/29 Yet more preparation for reference backendsMichael Haggerty, Apr 27, 2016
  2. 01/29 safe_create_leading_directories(): improve docstringMichael Haggerty, Apr 27, 2016
  3. 02/29 remove_dir_recursively(): add docstringMichael Haggerty, Apr 27, 2016
  4. 03/29 refname_is_safe(): use skip_prefix()Michael Haggerty, Apr 27, 2016
  5. 04/29 refname_is_safe(): don't allow the empty stringMichael Haggerty, Apr 27, 2016
  6. 05/29 refname_is_safe(): insist that the refname already be normalizedMichael Haggerty, Apr 27, 2016
  7. Junio C HamanoApr 27, 2016
  8. David TurnerApr 27, 2016
  9. Jeff KingApr 27, 2016
  10. David TurnerApr 27, 2016
  11. Jeff KingApr 27, 2016
  12. Jeff KingApr 27, 2016
  13. David TurnerApr 28, 2016
  14. 06/29 commit_ref_update(): write error message to *err, not stderrMichael Haggerty, Apr 27, 2016
  15. 07/29 rename_ref(): remove unneeded local variableMichael Haggerty, Apr 27, 2016
  16. 08/29 ref_transaction_commit(): remove local variable nMichael Haggerty, Apr 27, 2016
  17. Junio C HamanoApr 27, 2016
  18. Junio C HamanoApr 27, 2016
  19. 09/29 read_raw_ref(): rename flags argument to typeMichael Haggerty, Apr 27, 2016
  20. 10/29 read_raw_ref(): clear *type at start of functionMichael Haggerty, Apr 27, 2016
  21. 11/29 read_raw_ref(): rename symref argument to referentMichael Haggerty, Apr 27, 2016
  22. 12/29 read_raw_ref(): improve docstringMichael Haggerty, Apr 27, 2016
  23. Junio C HamanoApr 27, 2016
  24. 13/29 lock_ref_sha1_basic(): remove unneeded local variableMichael Haggerty, Apr 27, 2016
  25. 14/29 refs: make error messages more consistentMichael Haggerty, Apr 27, 2016
  26. 15/29 ref_transaction_create(): disallow recursive pruningMichael Haggerty, Apr 27, 2016
  27. Junio C HamanoApr 27, 2016
  28. David TurnerApr 27, 2016
  29. Junio C HamanoApr 27, 2016
  30. Junio C HamanoApr 27, 2016
  31. David TurnerApr 28, 2016
  32. Junio C HamanoApr 28, 2016
  33. Michael HaggertyApr 29, 2016
  34. Junio C HamanoApr 29, 2016
  35. Junio C HamanoApr 29, 2016
  36. Michael HaggertyApr 29, 2016
  37. 16/29 ref_transaction_commit(): correctly report close_ref() failureMichael Haggerty, Apr 27, 2016
  38. 17/29 delete_branches(): use resolve_refdup()Michael Haggerty, Apr 27, 2016
  39. 18/29 refs: allow log-only updatesMichael Haggerty, Apr 27, 2016
  40. 19/29 refs: don't dereference on renameMichael Haggerty, Apr 27, 2016
  41. Junio C HamanoApr 27, 2016
  42. Michael HaggertyApr 29, 2016
  43. Junio C HamanoApr 29, 2016
  44. Michael HaggertyApr 29, 2016
  45. Jeff KingApr 29, 2016
  46. Michael HaggertyApr 29, 2016
  47. Jeff KingApr 29, 2016
  48. Junio C HamanoApr 29, 2016
  49. David TurnerApr 29, 2016
  50. Michael HaggertyApr 30, 2016
  51. Junio C HamanoMay 2, 2016
  52. 20/29 verify_refname_available(): adjust constness in declarationMichael Haggerty, Apr 27, 2016
  53. 21/29 add_update(): initialize the whole ref_updateMichael Haggerty, Apr 27, 2016
  54. 22/29 lock_ref_for_update(): new functionMichael Haggerty, Apr 27, 2016
  55. 23/29 unlock_ref(): move definition higher in the fileMichael Haggerty, Apr 27, 2016
  56. 24/29 ref_transaction_update(): check refname_is_safe() at a minimumMichael Haggerty, Apr 27, 2016
  57. Junio C HamanoApr 27, 2016
  58. Michael HaggertyApr 29, 2016
  59. Junio C HamanoApr 29, 2016
  60. 25/29 refs: resolve symbolic refs firstMichael Haggerty, Apr 27, 2016
  61. David TurnerApr 28, 2016
  62. Michael HaggertyApr 29, 2016
  63. David TurnerApr 29, 2016
  64. Junio C HamanoMay 2, 2016
  65. 26/29 lock_ref_for_update(): don't re-read non-symbolic referencesMichael Haggerty, Apr 27, 2016
  66. 27/29 lock_ref_for_update(): don't resolve symrefsMichael Haggerty, Apr 27, 2016
  67. 28/29 commit_ref_update(): remove the flags parameterMichael Haggerty, Apr 27, 2016
  68. 29/29 lock_ref_sha1_basic(): only handle REF_NODEREF modeMichael Haggerty, Apr 27, 2016
  69. Junio C HamanoApr 29, 2016
  70. David TurnerApr 29, 2016

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.