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

[PATCH v5 25/26] refs: break out ref conflict checks

From
David Turner <dturner@twopensource.com>
Date
Oct 28, 2015, 02:14 UTC
Message-ID
<1445998467-11511-26-git-send-email-dturner@twopensource.com>
In-Reply-To
<1445998467-11511-1-git-send-email-dturner@twopensource.com>

Create new function verify_no_descendants, to hold one of the ref conflict checks used in verify_refname_available. Multiple backends will need this function, so it goes in the common code.

rename_ref_available also moves to the common code, because alternate backends might need it and it has no files-backend-specific code.

Signed-off-by: David Turner <dturner@twopensource.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
 refs-be-files.c | 49 ++++++++-----------------------------------------
 refs.c          | 38 ++++++++++++++++++++++++++++++++++++++
 refs.h          | 15 +++++++++++++++
 3 files changed, 61 insertions(+), 41 deletions(-)
diff --git a/refs-be-files.c b/refs-be-files.c
index 0eabea9..97a5983 100644
--- a/refs-be-files.c
+++ b/refs-be-files.c
@@ -729,6 +729,7 @@ static int verify_refname_available_dir(const char *refname,
 					struct strbuf *err)
 {
 	const char *slash;
+	const char *extra_refname;
 	int pos;
 	struct strbuf dirname = STRBUF_INIT;
 	int ret = -1;
@@ -834,33 +835,15 @@ static int verify_refname_available_dir(const char *refname,
 		}
 	}
 
-	if (extras) {
-		/*
-		 * Check for entries in extras that start with
-		 * "$refname/". We do that by looking for the place
-		 * where "$refname/" would be inserted in extras. If
-		 * there is an entry at that position that starts with
-		 * "$refname/" and is not in skip, then we have a
-		 * conflict.
-		 */
-		for (pos = string_list_find_insert_index(extras, dirname.buf, 0);
-		     pos < extras->nr; pos++) {
-			const char *extra_refname = extras->items[pos].string;
-
-			if (!starts_with(extra_refname, dirname.buf))
-				break;
-
-			if (!skip || !string_list_has_string(skip, extra_refname)) {
-				strbuf_addf(err, "cannot process '%s' and '%s' at the same time",
-					    refname, extra_refname);
-				goto cleanup;
-			}
-		}
+	extra_refname = find_descendant_ref(dirname.buf, extras, skip);
+	if (extra_refname) {
+		strbuf_addf(err,
+			    "cannot process '%s' and '%s' at the same time",
+			    refname, extra_refname);
+	} else {
+		ret = 0;
 	}
 
-	/* No conflicts were found */
-	ret = 0;
-
 cleanup:
 	strbuf_release(&dirname);
 	return ret;
@@ -2460,22 +2443,6 @@ out:
 	return ret;
 }
 
-static int rename_ref_available(const char *oldname, const char *newname)
-{
-	struct string_list skip = STRING_LIST_INIT_NODUP;
-	struct strbuf err = STRBUF_INIT;
-	int ret;
-
-	string_list_insert(&skip, oldname);
-	ret = !verify_refname_available(newname, NULL, &skip, &err);
-	if (!ret)
-		error("%s", err.buf);
-
-	string_list_clear(&skip, 0);
-	strbuf_release(&err);
-	return ret;
-}
-
 static int write_ref_to_lockfile(struct ref_lock *lock,
 				 const unsigned char *sha1, struct strbuf *err);
 static int commit_ref_update(struct ref_lock *lock,
diff --git a/refs.c b/refs.c
index 056c172..5d8b6ea 100644
--- a/refs.c
+++ b/refs.c
@@ -1027,3 +1027,41 @@ enum peel_status peel_object(const unsigned char *name, unsigned char *sha1)
 	hashcpy(sha1, o->sha1);
 	return PEEL_PEELED;
 }
+
+const char *find_descendant_ref(const char *dirname,
+				const struct string_list *extras,
+				const struct string_list *skip)
+{
+	int pos;
+	if (!extras)
+		return NULL;
+
+	/* Look for the place where dirname would be inserted in extras. */
+	for (pos = string_list_find_insert_index(extras, dirname, 0);
+	     pos < extras->nr; pos++) {
+		const char *extra_refname = extras->items[pos].string;
+
+		if (!starts_with(extra_refname, dirname))
+			break;
+
+		if (!skip || !string_list_has_string(skip, extra_refname))
+			return extra_refname;
+	}
+	return NULL;
+}
+
+int rename_ref_available(const char *oldname, const char *newname)
+{
+	struct string_list skip = STRING_LIST_INIT_NODUP;
+	struct strbuf err = STRBUF_INIT;
+	int ret;
+
+	string_list_insert(&skip, oldname);
+	ret = !verify_refname_available(newname, NULL, &skip, &err);
+	if (!ret)
+		error("%s", err.buf);
+
+	string_list_clear(&skip, 0);
+	strbuf_release(&err);
+	return ret;
+}
diff --git a/refs.h b/refs.h
index f97a2e4..88fea3e 100644
--- a/refs.h
+++ b/refs.h
@@ -362,6 +362,8 @@ int pack_refs(unsigned int flags);
 int verify_refname_available(const char *newname, struct string_list *extra,
 			     struct string_list *skip, struct strbuf *err);
 
+int rename_ref_available(const char *oldname, const char *newname);
+
 extern int is_branch(const char *refname);
 
 /*
@@ -623,6 +625,19 @@ int files_log_ref_write(const char *refname, const unsigned char *old_sha1,
 			const unsigned char *new_sha1, const char *msg,
 			int flags, struct strbuf *err);
 
+/*
+ * Check for entries in extras that are within the specified
+ * directory, where dirname is a reference directory name including
+ * the trailing slash (e.g., "refs/heads/master/"). Ignore any
+ * conflicting references that are found in skip. If there is a
+ * conflicting reference, return its name.
+ *
+ * extras and skip must be sorted lists of reference names. skip can
+ * be NULL; extras cannot.
+ */
+const char *find_descendant_ref(const char *dirname,
+				const struct string_list *extras,
+				const struct string_list *skip);
 
 enum expire_reflog_flags {
 	EXPIRE_REFLOGS_DRY_RUN = 1 << 0,
-- 
2.4.2.658.g6d8523e-twtrsrc
Previous: David TurnerNext: Michael Haggerty
Message 29 of 67 in “refs backend pre-vtable”
  1. 00/26 refs backend pre-vtableDavid Turner, Oct 28, 2015
  2. 01/26 refs.c: create a public version of verify_refname_availableDavid Turner, Oct 28, 2015
  3. 02/26 refs: make is_branch publicDavid Turner, Oct 28, 2015
  4. 03/26 refs-be-files.c: rename refs to refs-be-filesDavid Turner, Oct 28, 2015
  5. 04/26 refs.c: add a new refs.c file to hold all common refs codeDavid Turner, Oct 28, 2015
  6. 05/26 refs.c: move update_ref to refs.cDavid Turner, Oct 28, 2015
  7. 06/26 refs.c: move delete_pseudoref and delete_ref to the common codeDavid Turner, Oct 28, 2015
  8. 07/26 refs.c: move read_ref_at to the common refs fileDavid Turner, Oct 28, 2015
  9. 08/26 refs.c: move the hidden refs functions to the common codeDavid Turner, Oct 28, 2015
  10. 09/26 refs.c: move dwim and friend functions to the common refs codeDavid Turner, Oct 28, 2015
  11. 10/26 refs.c: move warn_if_dangling_symref* to the common codeDavid Turner, Oct 28, 2015
  12. 11/26 refs.c: move read_ref, read_ref_full and ref_exists to the common codeDavid Turner, Oct 28, 2015
  13. 12/26 refs.c: move resolve_refdup to commonDavid Turner, Oct 28, 2015
  14. 13/26 refs.c: move check_refname_format to the common codeDavid Turner, Oct 28, 2015
  15. 14/26 refs.c: move is_branch to the common codeDavid Turner, Oct 28, 2015
  16. 15/26 refs.c: move prettify_refname to the common codeDavid Turner, Oct 28, 2015
  17. 16/26 refs.c: move ref iterators to the common codeDavid Turner, Oct 28, 2015
  18. Michael HaggertyNov 1, 2015
  19. 17/26 refs.c: move head_ref_namespaced to the common codeDavid Turner, Oct 28, 2015
  20. 18/26 refs: move transaction functions into common codeDavid Turner, Oct 28, 2015
  21. Michael HaggertyNov 1, 2015
  22. David TurnerNov 2, 2015
  23. 19/26 refs.c: move refname_is_safe to the common codeDavid Turner, Oct 28, 2015
  24. 20/26 refs.c: move copy_msg to the common codeDavid Turner, Oct 28, 2015
  25. 21/26 refs.c: move peel_object to the common codeDavid Turner, Oct 28, 2015
  26. 22/26 refs.c: move should_autocreate_reflog to common codeDavid Turner, Oct 28, 2015
  27. 23/26 initdb: move safe_create_dir into common codeDavid Turner, Oct 28, 2015
  28. 24/26 refs: make files_log_ref_write functions publicDavid Turner, Oct 28, 2015
  29. 25/26 refs: break out ref conflict checksDavid Turner, Oct 28, 2015
  30. Michael HaggertyNov 2, 2015
  31. 26/26 introduce "extensions" form of core.repositoryformatversionDavid Turner, Oct 28, 2015
  32. Michael HaggertyNov 3, 2015
  33. 00/25 refs backend pre-vtableMichael Haggerty, Nov 3, 2015
  34. 01/25 refs: make is_branch publicMichael Haggerty, Nov 3, 2015
  35. 02/25 refs/files-backend.c: new file, renamed from refs.cMichael Haggerty, Nov 3, 2015
  36. 03/25 refs: add a new file, refs/refs.c, to hold common refs codeMichael Haggerty, Nov 3, 2015
  37. 04/25 refs: move update_ref to refs/refs.cMichael Haggerty, Nov 3, 2015
  38. 05/25 refs: move delete_pseudoref and delete_ref to the common codeMichael Haggerty, Nov 3, 2015
  39. 06/25 refs: move read_ref_at to the common refs fileMichael Haggerty, Nov 3, 2015
  40. 07/25 refs: move the hidden refs functions to the common codeMichael Haggerty, Nov 3, 2015
  41. 08/25 refs: move dwim and friend functions to the common refs codeMichael Haggerty, Nov 3, 2015
  42. 09/25 refs: move warn_if_dangling_symref* to the common codeMichael Haggerty, Nov 3, 2015
  43. 10/25 refs: move read_ref, read_ref_full and ref_exists to the common codeMichael Haggerty, Nov 3, 2015
  44. 11/25 refs: move resolve_refdup to commonMichael Haggerty, Nov 3, 2015
  45. 12/25 refs: move check_refname_format to the common codeMichael Haggerty, Nov 3, 2015
  46. 13/25 refs: move is_branch to the common codeMichael Haggerty, Nov 3, 2015
  47. 14/25 refs: move prettify_refname to the common codeMichael Haggerty, Nov 3, 2015
  48. 15/25 refs: move ref iterators to the common codeMichael Haggerty, Nov 3, 2015
  49. 16/25 refs: move head_ref_namespaced to the common codeMichael Haggerty, Nov 3, 2015
  50. 17/25 refs: move transaction functions to the common codeMichael Haggerty, Nov 3, 2015
  51. 18/25 refs: move refname_is_safe to the common codeMichael Haggerty, Nov 3, 2015
  52. 19/25 refs: move copy_msg to the common codeMichael Haggerty, Nov 3, 2015
  53. 20/25 refs: move peel_object to the common codeMichael Haggerty, Nov 3, 2015
  54. 21/25 refs: move should_autocreate_reflog to common codeMichael Haggerty, Nov 3, 2015
  55. 22/25 initdb: make safe_create_dir publicMichael Haggerty, Nov 3, 2015
  56. 23/25 files_log_ref_write: new functionMichael Haggerty, Nov 3, 2015
  57. 24/25 refs: create a shared version of verify_refname_availableMichael Haggerty, Nov 3, 2015
  58. 25/25 refs: break out ref conflict checksMichael Haggerty, Nov 3, 2015
  59. David TurnerNov 4, 2015
  60. Michael HaggertyNov 5, 2015
  61. David TurnerNov 5, 2015
  62. Michael HaggertyNov 6, 2015
  63. Junio C HamanoNov 6, 2015
  64. Junio C HamanoNov 6, 2015
  65. Michael HaggertyNov 8, 2015
  66. Michael HaggertyNov 8, 2015
  67. Junio C HamanoNov 8, 2015

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.