git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v8 00/10] refs backend pre-vtable
@ 2015-11-10 11:42 Michael Haggerty
  2015-11-10 11:42 ` [PATCH v8 01/10] verify_refname_available(): rename function Michael Haggerty
                   ` (9 more replies)
  0 siblings, 10 replies; 13+ messages in thread
From: Michael Haggerty @ 2015-11-10 11:42 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Jeff King, David Turner, Lukas Fleischer, Ronnie Sahlberg,
	Ramsay Jones, git, Michael Haggerty

Another re-roll of this patch series, to address the comments of
Ramsay Jones (thanks!) about v7 [1].

This version has the following changes compared to v7:

* Drop "refs: make is_branch public" patch. This was already done
  quite a while ago:

      e7e0f26 refs.c: add a public is_branch function (2014-07-15)

* Instead of having refs-internal.h include refs.h, have the "*.c"
  files include both header files.

* Remove some unneeded includes from refs/files-backend.c.

Since patch 01/11 of v7 was omitted, the patches in this version are
numbered differently. In particular, it is now patches 01 through 07
that form the core of this patch series. The last three patches can
easily be postponed if that will speed the progress of the first
seven.

These patches are also available from my GitHub fork [2] as branch
"refs-backend-pre-vtable".

Michael

[1] http://article.gmane.org/gmane.comp.version-control.git/281057
[2] https://github.com/mhagger/git

David Turner (4):
  copy_msg(): rename to copy_reflog_msg()
  initdb: make safe_create_dir public
  files_log_ref_write: new function
  refs: break out ref conflict checks

Michael Haggerty (4):
  pack_if_possible_fn(): use ref_type() instead of is_per_worktree_ref()
  refname_is_safe(): improve docstring
  refs/refs-internal.h: new header file
  refs: split filesystem-based refs code into a new file

Ronnie Sahlberg (2):
  verify_refname_available(): rename function
  verify_refname_available(): new function

 Makefile                       |    3 +-
 builtin/init-db.c              |   12 -
 cache.h                        |    8 +
 path.c                         |   12 +
 refs.c                         | 3709 +---------------------------------------
 refs.c => refs/files-backend.c | 1286 +-------------
 refs/refs-internal.h           |  200 +++
 7 files changed, 311 insertions(+), 4919 deletions(-)
 copy refs.c => refs/files-backend.c (75%)
 create mode 100644 refs/refs-internal.h

-- 
2.6.2

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH v8 01/10] verify_refname_available(): rename function
  2015-11-10 11:42 [PATCH v8 00/10] refs backend pre-vtable Michael Haggerty
@ 2015-11-10 11:42 ` Michael Haggerty
  2015-11-10 11:42 ` [PATCH v8 02/10] verify_refname_available(): new function Michael Haggerty
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Michael Haggerty @ 2015-11-10 11:42 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Jeff King, David Turner, Lukas Fleischer, Ronnie Sahlberg,
	Ramsay Jones, git, Ronnie Sahlberg, Michael Haggerty

From: Ronnie Sahlberg <sahlberg@google.com>

Rename verify_refname_available() to verify_refname_available_dir() to
make the old name available for a more general purpose.

Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>
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.c | 44 ++++++++++++++++++++++----------------------
 1 file changed, 22 insertions(+), 22 deletions(-)

diff --git a/refs.c b/refs.c
index 132eff5..0617e0c 100644
--- a/refs.c
+++ b/refs.c
@@ -279,7 +279,7 @@ struct ref_dir {
  * presence of an empty subdirectory does not block the creation of a
  * similarly-named reference.  (The fact that reference names with the
  * same leading components can conflict *with each other* is a
- * separate issue that is regulated by verify_refname_available().)
+ * separate issue that is regulated by verify_refname_available_dir().)
  *
  * Please note that the name field contains the fully-qualified
  * reference (or subdirectory) name.  Space could be saved by only
@@ -911,11 +911,11 @@ static int nonmatching_ref_fn(struct ref_entry *entry, void *vdata)
  *
  * extras and skip must be sorted.
  */
-static int verify_refname_available(const char *refname,
-				    const struct string_list *extras,
-				    const struct string_list *skip,
-				    struct ref_dir *dir,
-				    struct strbuf *err)
+static int verify_refname_available_dir(const char *refname,
+					const struct string_list *extras,
+					const struct string_list *skip,
+					struct ref_dir *dir,
+					struct strbuf *err)
 {
 	const char *slash;
 	int pos;
@@ -2465,8 +2465,8 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname,
 		strbuf_git_path(&orig_ref_file, "%s", orig_refname);
 		if (remove_empty_directories(&orig_ref_file)) {
 			last_errno = errno;
-			if (!verify_refname_available(orig_refname, extras, skip,
-						      get_loose_refs(&ref_cache), err))
+			if (!verify_refname_available_dir(orig_refname, extras, skip,
+							  get_loose_refs(&ref_cache), err))
 				strbuf_addf(err, "there are still refs under '%s'",
 					    orig_refname);
 			goto error_return;
@@ -2479,8 +2479,8 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname,
 	if (!refname) {
 		last_errno = errno;
 		if (last_errno != ENOTDIR ||
-		    !verify_refname_available(orig_refname, extras, skip,
-					      get_loose_refs(&ref_cache), err))
+		    !verify_refname_available_dir(orig_refname, extras, skip,
+						  get_loose_refs(&ref_cache), err))
 			strbuf_addf(err, "unable to resolve reference %s: %s",
 				    orig_refname, strerror(last_errno));
 
@@ -2493,8 +2493,8 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname,
 	 * our refname.
 	 */
 	if (is_null_oid(&lock->old_oid) &&
-	    verify_refname_available(refname, extras, skip,
-				     get_packed_refs(&ref_cache), err)) {
+	    verify_refname_available_dir(refname, extras, skip,
+					 get_packed_refs(&ref_cache), err)) {
 		last_errno = ENOTDIR;
 		goto error_return;
 	}
@@ -3127,10 +3127,10 @@ static int rename_ref_available(const char *oldname, const char *newname)
 	int ret;
 
 	string_list_insert(&skip, oldname);
-	ret = !verify_refname_available(newname, NULL, &skip,
-					get_packed_refs(&ref_cache), &err)
-		&& !verify_refname_available(newname, NULL, &skip,
-					     get_loose_refs(&ref_cache), &err);
+	ret = !verify_refname_available_dir(newname, NULL, &skip,
+					    get_packed_refs(&ref_cache), &err)
+		&& !verify_refname_available_dir(newname, NULL, &skip,
+						 get_loose_refs(&ref_cache), &err);
 	if (!ret)
 		error("%s", err.buf);
 
@@ -4376,12 +4376,12 @@ int initial_ref_transaction_commit(struct ref_transaction *transaction,
 		if ((update->flags & REF_HAVE_OLD) &&
 		    !is_null_sha1(update->old_sha1))
 			die("BUG: initial ref transaction with old_sha1 set");
-		if (verify_refname_available(update->refname,
-					     &affected_refnames, NULL,
-					     loose_refs, err) ||
-		    verify_refname_available(update->refname,
-					     &affected_refnames, NULL,
-					     packed_refs, err)) {
+		if (verify_refname_available_dir(update->refname,
+						 &affected_refnames, NULL,
+						 loose_refs, err) ||
+		    verify_refname_available_dir(update->refname,
+						 &affected_refnames, NULL,
+						 packed_refs, err)) {
 			ret = TRANSACTION_NAME_CONFLICT;
 			goto cleanup;
 		}
-- 
2.6.2

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v8 02/10] verify_refname_available(): new function
  2015-11-10 11:42 [PATCH v8 00/10] refs backend pre-vtable Michael Haggerty
  2015-11-10 11:42 ` [PATCH v8 01/10] verify_refname_available(): rename function Michael Haggerty
@ 2015-11-10 11:42 ` Michael Haggerty
  2015-11-10 11:42 ` [PATCH v8 03/10] copy_msg(): rename to copy_reflog_msg() Michael Haggerty
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Michael Haggerty @ 2015-11-10 11:42 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Jeff King, David Turner, Lukas Fleischer, Ronnie Sahlberg,
	Ramsay Jones, git, Ronnie Sahlberg, Michael Haggerty

From: Ronnie Sahlberg <sahlberg@google.com>

Add a new verify_refname_available() function, which checks whether the
refname is available for use, taking all references (both packed and
loose) into account. This function, unlike the old
verify_refname_available(), has semantics independent of the choice of
reference storage, and can therefore be implemented by alternative
reference backends.

Use the new function in a couple of places.

Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>
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.c | 66 ++++++++++++++++++++++++++++++++++++++++--------------------------
 1 file changed, 40 insertions(+), 26 deletions(-)

diff --git a/refs.c b/refs.c
index 0617e0c..ddcdf81 100644
--- a/refs.c
+++ b/refs.c
@@ -279,7 +279,7 @@ struct ref_dir {
  * presence of an empty subdirectory does not block the creation of a
  * similarly-named reference.  (The fact that reference names with the
  * same leading components can conflict *with each other* is a
- * separate issue that is regulated by verify_refname_available_dir().)
+ * separate issue that is regulated by verify_refname_available().)
  *
  * Please note that the name field contains the fully-qualified
  * reference (or subdirectory) name.  Space could be saved by only
@@ -897,19 +897,7 @@ static int nonmatching_ref_fn(struct ref_entry *entry, void *vdata)
 /*
  * Return 0 if a reference named refname could be created without
  * conflicting with the name of an existing reference in dir.
- * Otherwise, return a negative value and write an explanation to err.
- * If extras is non-NULL, it is a list of additional refnames with
- * which refname is not allowed to conflict. If skip is non-NULL,
- * ignore potential conflicts with refs in skip (e.g., because they
- * are scheduled for deletion in the same operation). Behavior is
- * undefined if the same name is listed in both extras and skip.
- *
- * Two reference names conflict if one of them exactly matches the
- * leading components of the other; e.g., "refs/foo/bar" conflicts
- * with both "refs/foo" and with "refs/foo/bar/baz" but not with
- * "refs/foo/bar" or "refs/foo/barbados".
- *
- * extras and skip must be sorted.
+ * See verify_refname_available for more information.
  */
 static int verify_refname_available_dir(const char *refname,
 					const struct string_list *extras,
@@ -3120,6 +3108,40 @@ out:
 	return ret;
 }
 
+/*
+ * Return 0 if a reference named refname could be created without
+ * conflicting with the name of an existing reference. Otherwise,
+ * return a negative value and write an explanation to err. If extras
+ * is non-NULL, it is a list of additional refnames with which refname
+ * is not allowed to conflict. If skip is non-NULL, ignore potential
+ * conflicts with refs in skip (e.g., because they are scheduled for
+ * deletion in the same operation). Behavior is undefined if the same
+ * name is listed in both extras and skip.
+ *
+ * Two reference names conflict if one of them exactly matches the
+ * leading components of the other; e.g., "foo/bar" conflicts with
+ * both "foo" and with "foo/bar/baz" but not with "foo/bar" or
+ * "foo/barbados".
+ *
+ * extras and skip must be sorted.
+ */
+static int verify_refname_available(const char *newname,
+				    struct string_list *extras,
+				    struct string_list *skip,
+				    struct strbuf *err)
+{
+	struct ref_dir *packed_refs = get_packed_refs(&ref_cache);
+	struct ref_dir *loose_refs = get_loose_refs(&ref_cache);
+
+	if (verify_refname_available_dir(newname, extras, skip,
+					 packed_refs, err) ||
+	    verify_refname_available_dir(newname, extras, skip,
+					 loose_refs, err))
+		return -1;
+
+	return 0;
+}
+
 static int rename_ref_available(const char *oldname, const char *newname)
 {
 	struct string_list skip = STRING_LIST_INIT_NODUP;
@@ -3127,10 +3149,7 @@ static int rename_ref_available(const char *oldname, const char *newname)
 	int ret;
 
 	string_list_insert(&skip, oldname);
-	ret = !verify_refname_available_dir(newname, NULL, &skip,
-					    get_packed_refs(&ref_cache), &err)
-		&& !verify_refname_available_dir(newname, NULL, &skip,
-						 get_loose_refs(&ref_cache), &err);
+	ret = !verify_refname_available(newname, NULL, &skip, &err);
 	if (!ret)
 		error("%s", err.buf);
 
@@ -4334,8 +4353,6 @@ static int ref_present(const char *refname,
 int initial_ref_transaction_commit(struct ref_transaction *transaction,
 				   struct strbuf *err)
 {
-	struct ref_dir *loose_refs = get_loose_refs(&ref_cache);
-	struct ref_dir *packed_refs = get_packed_refs(&ref_cache);
 	int ret = 0, i;
 	int n = transaction->nr;
 	struct ref_update **updates = transaction->updates;
@@ -4376,12 +4393,9 @@ int initial_ref_transaction_commit(struct ref_transaction *transaction,
 		if ((update->flags & REF_HAVE_OLD) &&
 		    !is_null_sha1(update->old_sha1))
 			die("BUG: initial ref transaction with old_sha1 set");
-		if (verify_refname_available_dir(update->refname,
-						 &affected_refnames, NULL,
-						 loose_refs, err) ||
-		    verify_refname_available_dir(update->refname,
-						 &affected_refnames, NULL,
-						 packed_refs, err)) {
+		if (verify_refname_available(update->refname,
+					     &affected_refnames, NULL,
+					     err)) {
 			ret = TRANSACTION_NAME_CONFLICT;
 			goto cleanup;
 		}
-- 
2.6.2

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v8 03/10] copy_msg(): rename to copy_reflog_msg()
  2015-11-10 11:42 [PATCH v8 00/10] refs backend pre-vtable Michael Haggerty
  2015-11-10 11:42 ` [PATCH v8 01/10] verify_refname_available(): rename function Michael Haggerty
  2015-11-10 11:42 ` [PATCH v8 02/10] verify_refname_available(): new function Michael Haggerty
@ 2015-11-10 11:42 ` Michael Haggerty
  2015-11-10 11:42 ` [PATCH v8 04/10] pack_if_possible_fn(): use ref_type() instead of is_per_worktree_ref() Michael Haggerty
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Michael Haggerty @ 2015-11-10 11:42 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Jeff King, David Turner, Lukas Fleischer, Ronnie Sahlberg,
	Ramsay Jones, git, Michael Haggerty

From: David Turner <dturner@twopensource.com>

We will soon increase the visibility of this function, so make its name
more distinctive.

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.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/refs.c b/refs.c
index ddcdf81..480de9a 100644
--- a/refs.c
+++ b/refs.c
@@ -3287,7 +3287,7 @@ static int commit_ref(struct ref_lock *lock)
  * large, while cleaning up the whitespaces.  Especially, convert LF to space,
  * because reflog file is one line per entry.
  */
-static int copy_msg(char *buf, const char *msg)
+static int copy_reflog_msg(char *buf, const char *msg)
 {
 	char *cp = buf;
 	char c;
@@ -3391,7 +3391,7 @@ static int log_ref_write_fd(int fd, const unsigned char *old_sha1,
 			sha1_to_hex(new_sha1),
 			committer);
 	if (msglen)
-		len += copy_msg(logrec + len - 1, msg) - 1;
+		len += copy_reflog_msg(logrec + len - 1, msg) - 1;
 
 	written = len <= maxlen ? write_in_full(fd, logrec, len) : -1;
 	free(logrec);
-- 
2.6.2

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v8 04/10] pack_if_possible_fn(): use ref_type() instead of is_per_worktree_ref()
  2015-11-10 11:42 [PATCH v8 00/10] refs backend pre-vtable Michael Haggerty
                   ` (2 preceding siblings ...)
  2015-11-10 11:42 ` [PATCH v8 03/10] copy_msg(): rename to copy_reflog_msg() Michael Haggerty
@ 2015-11-10 11:42 ` Michael Haggerty
  2015-11-10 11:42 ` [PATCH v8 05/10] refname_is_safe(): improve docstring Michael Haggerty
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Michael Haggerty @ 2015-11-10 11:42 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Jeff King, David Turner, Lukas Fleischer, Ronnie Sahlberg,
	Ramsay Jones, git, Michael Haggerty

is_per_worktree_ref() will soon be made private, so use the public
interface, ref_type(), in its place. And now that we're using
ref_type(), we can make it clear that we won't pack pseudorefs. This was
the case before, but due to the not-so-obvious reason that this function
is applied to references via the loose reference cache, which only
includes references that live inside "refs/".

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
 refs.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/refs.c b/refs.c
index 480de9a..82129f0 100644
--- a/refs.c
+++ b/refs.c
@@ -2671,8 +2671,6 @@ struct pack_refs_cb_data {
 	struct ref_to_prune *ref_to_prune;
 };
 
-static int is_per_worktree_ref(const char *refname);
-
 /*
  * An each_ref_entry_fn that is run over loose references only.  If
  * the loose reference can be packed, add an entry in the packed ref
@@ -2687,7 +2685,7 @@ static int pack_if_possible_fn(struct ref_entry *entry, void *cb_data)
 	int is_tag_ref = starts_with(entry->name, "refs/tags/");
 
 	/* Do not pack per-worktree refs: */
-	if (is_per_worktree_ref(entry->name))
+	if (ref_type(entry->name) != REF_TYPE_NORMAL)
 		return 0;
 
 	/* ALWAYS pack tags */
-- 
2.6.2

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v8 05/10] refname_is_safe(): improve docstring
  2015-11-10 11:42 [PATCH v8 00/10] refs backend pre-vtable Michael Haggerty
                   ` (3 preceding siblings ...)
  2015-11-10 11:42 ` [PATCH v8 04/10] pack_if_possible_fn(): use ref_type() instead of is_per_worktree_ref() Michael Haggerty
@ 2015-11-10 11:42 ` Michael Haggerty
  2015-11-10 11:42 ` [PATCH v8 06/10] refs/refs-internal.h: new header file Michael Haggerty
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Michael Haggerty @ 2015-11-10 11:42 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Jeff King, David Turner, Lukas Fleischer, Ronnie Sahlberg,
	Ramsay Jones, git, Michael Haggerty

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
 refs.c | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/refs.c b/refs.c
index 82129f0..f48c58a 100644
--- a/refs.c
+++ b/refs.c
@@ -341,13 +341,17 @@ static struct ref_dir *get_ref_dir(struct ref_entry *entry)
 }
 
 /*
- * Check if a refname is safe.
- * For refs that start with "refs/" we consider it safe as long they do
- * not try to resolve to outside of refs/.
+ * Return true iff refname is minimally safe. "Safe" here means that
+ * deleting a loose reference by this name will not do any damage, for
+ * example by causing a file that is not a reference to be deleted.
+ * This function does not check that the reference name is legal; for
+ * that, use check_refname_format().
  *
- * For all other refs we only consider them safe iff they only contain
- * upper case characters and '_' (like "HEAD" AND "MERGE_HEAD", and not like
- * "config").
+ * We consider a refname that starts with "refs/" to be safe as long
+ * as any ".." components that it might contain do not escape "refs/".
+ * Names that do not start with "refs/" are considered safe iff they
+ * consist entirely of upper case characters and '_' (like "HEAD" and
+ * "MERGE_HEAD" but not "config" or "FOO/BAR").
  */
 static int refname_is_safe(const char *refname)
 {
-- 
2.6.2

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v8 06/10] refs/refs-internal.h: new header file
  2015-11-10 11:42 [PATCH v8 00/10] refs backend pre-vtable Michael Haggerty
                   ` (4 preceding siblings ...)
  2015-11-10 11:42 ` [PATCH v8 05/10] refname_is_safe(): improve docstring Michael Haggerty
@ 2015-11-10 11:42 ` Michael Haggerty
  2015-11-10 11:42 ` [PATCH v8 08/10] initdb: make safe_create_dir public Michael Haggerty
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Michael Haggerty @ 2015-11-10 11:42 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Jeff King, David Turner, Lukas Fleischer, Ronnie Sahlberg,
	Ramsay Jones, git, Michael Haggerty

There are a number of constants, structs, and static functions defined
in refs.c and treated as private to the references module. But we want
to support multiple reference backends within the reference module,
and those backends will need access to some heretofore private
declarations.

We don't want those declarations to be visible to non-refs code, so we
don't want to move them to refs.h. Instead, add a new header file,
refs/refs-internal.h, that is intended to be included only from within
the refs module. Make some functions non-static and move some
declarations (and their corresponding docstrings) from refs.c to this
file.

In a moment we will add more content to the "refs" subdirectory.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
 refs.c               | 174 +++----------------------------------------------
 refs/refs-internal.h | 180 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 189 insertions(+), 165 deletions(-)
 create mode 100644 refs/refs-internal.h

diff --git a/refs.c b/refs.c
index f48c58a..e6b82ee 100644
--- a/refs.c
+++ b/refs.c
@@ -1,6 +1,7 @@
 #include "cache.h"
 #include "lockfile.h"
 #include "refs.h"
+#include "refs/refs-internal.h"
 #include "object.h"
 #include "tag.h"
 #include "dir.h"
@@ -35,41 +36,6 @@ static unsigned char refname_disposition[256] = {
 };
 
 /*
- * Flag passed to lock_ref_sha1_basic() telling it to tolerate broken
- * refs (i.e., because the reference is about to be deleted anyway).
- */
-#define REF_DELETING	0x02
-
-/*
- * Used as a flag in ref_update::flags when a loose ref is being
- * pruned.
- */
-#define REF_ISPRUNING	0x04
-
-/*
- * Used as a flag in ref_update::flags when the reference should be
- * updated to new_sha1.
- */
-#define REF_HAVE_NEW	0x08
-
-/*
- * Used as a flag in ref_update::flags when old_sha1 should be
- * checked.
- */
-#define REF_HAVE_OLD	0x10
-
-/*
- * Used as a flag in ref_update::flags when the lockfile needs to be
- * committed.
- */
-#define REF_NEEDS_COMMIT 0x20
-
-/*
- * 0x40 is REF_FORCE_CREATE_REFLOG, so skip it if you're adding a
- * value to ref_update::flags
- */
-
-/*
  * Try to read one refname component from the front of refname.
  * Return the length of the component found, or -1 if the component is
  * not legal.  It is legal if it is something reasonable to have under
@@ -340,20 +306,7 @@ static struct ref_dir *get_ref_dir(struct ref_entry *entry)
 	return dir;
 }
 
-/*
- * Return true iff refname is minimally safe. "Safe" here means that
- * deleting a loose reference by this name will not do any damage, for
- * example by causing a file that is not a reference to be deleted.
- * This function does not check that the reference name is legal; for
- * that, use check_refname_format().
- *
- * We consider a refname that starts with "refs/" to be safe as long
- * as any ".." components that it might contain do not escape "refs/".
- * Names that do not start with "refs/" are considered safe iff they
- * consist entirely of upper case characters and '_' (like "HEAD" and
- * "MERGE_HEAD" but not "config" or "FOO/BAR").
- */
-static int refname_is_safe(const char *refname)
+int refname_is_safe(const char *refname)
 {
 	if (starts_with(refname, "refs/")) {
 		char *buf;
@@ -1823,39 +1776,7 @@ static int filter_refs(const char *refname, const struct object_id *oid,
 	return filter->fn(refname, oid, flags, filter->cb_data);
 }
 
-enum peel_status {
-	/* object was peeled successfully: */
-	PEEL_PEELED = 0,
-
-	/*
-	 * object cannot be peeled because the named object (or an
-	 * object referred to by a tag in the peel chain), does not
-	 * exist.
-	 */
-	PEEL_INVALID = -1,
-
-	/* object cannot be peeled because it is not a tag: */
-	PEEL_NON_TAG = -2,
-
-	/* ref_entry contains no peeled value because it is a symref: */
-	PEEL_IS_SYMREF = -3,
-
-	/*
-	 * ref_entry cannot be peeled because it is broken (i.e., the
-	 * symbolic reference cannot even be resolved to an object
-	 * name):
-	 */
-	PEEL_BROKEN = -4
-};
-
-/*
- * Peel the named object; i.e., if the object is a tag, resolve the
- * tag recursively until a non-tag is found.  If successful, store the
- * result to sha1 and return PEEL_PEELED.  If the object is not a tag
- * or is not valid, return PEEL_NON_TAG or PEEL_INVALID, respectively,
- * and leave sha1 unchanged.
- */
-static enum peel_status peel_object(const unsigned char *name, unsigned char *sha1)
+enum peel_status peel_object(const unsigned char *name, unsigned char *sha1)
 {
 	struct object *o = lookup_unknown_object(name);
 
@@ -3110,27 +3031,10 @@ out:
 	return ret;
 }
 
-/*
- * Return 0 if a reference named refname could be created without
- * conflicting with the name of an existing reference. Otherwise,
- * return a negative value and write an explanation to err. If extras
- * is non-NULL, it is a list of additional refnames with which refname
- * is not allowed to conflict. If skip is non-NULL, ignore potential
- * conflicts with refs in skip (e.g., because they are scheduled for
- * deletion in the same operation). Behavior is undefined if the same
- * name is listed in both extras and skip.
- *
- * Two reference names conflict if one of them exactly matches the
- * leading components of the other; e.g., "foo/bar" conflicts with
- * both "foo" and with "foo/bar/baz" but not with "foo/bar" or
- * "foo/barbados".
- *
- * extras and skip must be sorted.
- */
-static int verify_refname_available(const char *newname,
-				    struct string_list *extras,
-				    struct string_list *skip,
-				    struct strbuf *err)
+int verify_refname_available(const char *newname,
+			     struct string_list *extras,
+			     struct string_list *skip,
+			     struct strbuf *err)
 {
 	struct ref_dir *packed_refs = get_packed_refs(&ref_cache);
 	struct ref_dir *loose_refs = get_loose_refs(&ref_cache);
@@ -3284,12 +3188,7 @@ static int commit_ref(struct ref_lock *lock)
 	return 0;
 }
 
-/*
- * copy the reflog message msg to buf, which has been allocated sufficiently
- * large, while cleaning up the whitespaces.  Especially, convert LF to space,
- * because reflog file is one line per entry.
- */
-static int copy_reflog_msg(char *buf, const char *msg)
+int copy_reflog_msg(char *buf, const char *msg)
 {
 	char *cp = buf;
 	char c;
@@ -3310,7 +3209,7 @@ static int copy_reflog_msg(char *buf, const char *msg)
 	return cp - buf;
 }
 
-static int should_autocreate_reflog(const char *refname)
+int should_autocreate_reflog(const char *refname)
 {
 	if (!log_all_ref_updates)
 		return 0;
@@ -3963,61 +3862,6 @@ int for_each_reflog(each_ref_fn fn, void *cb_data)
 	return retval;
 }
 
-/**
- * Information needed for a single ref update. Set new_sha1 to the new
- * value or to null_sha1 to delete the ref. To check the old value
- * while the ref is locked, set (flags & REF_HAVE_OLD) and set
- * old_sha1 to the old value, or to null_sha1 to ensure the ref does
- * not exist before update.
- */
-struct ref_update {
-	/*
-	 * If (flags & REF_HAVE_NEW), set the reference to this value:
-	 */
-	unsigned char new_sha1[20];
-	/*
-	 * If (flags & REF_HAVE_OLD), check that the reference
-	 * previously had this value:
-	 */
-	unsigned char old_sha1[20];
-	/*
-	 * One or more of REF_HAVE_NEW, REF_HAVE_OLD, REF_NODEREF,
-	 * REF_DELETING, and REF_ISPRUNING:
-	 */
-	unsigned int flags;
-	struct ref_lock *lock;
-	int type;
-	char *msg;
-	const char refname[FLEX_ARRAY];
-};
-
-/*
- * Transaction states.
- * OPEN:   The transaction is in a valid state and can accept new updates.
- *         An OPEN transaction can be committed.
- * CLOSED: A closed transaction is no longer active and no other operations
- *         than free can be used on it in this state.
- *         A transaction can either become closed by successfully committing
- *         an active transaction or if there is a failure while building
- *         the transaction thus rendering it failed/inactive.
- */
-enum ref_transaction_state {
-	REF_TRANSACTION_OPEN   = 0,
-	REF_TRANSACTION_CLOSED = 1
-};
-
-/*
- * Data structure for holding a reference transaction, which can
- * consist of checks and updates to multiple references, carried out
- * as atomically as possible.  This structure is opaque to callers.
- */
-struct ref_transaction {
-	struct ref_update **updates;
-	size_t alloc;
-	size_t nr;
-	enum ref_transaction_state state;
-};
-
 struct ref_transaction *ref_transaction_begin(struct strbuf *err)
 {
 	assert(err);
diff --git a/refs/refs-internal.h b/refs/refs-internal.h
new file mode 100644
index 0000000..9077c11
--- /dev/null
+++ b/refs/refs-internal.h
@@ -0,0 +1,180 @@
+#ifndef REFS_REFS_INTERNAL_H
+#define REFS_REFS_INTERNAL_H
+
+/*
+ * Data structures and functions for the internal use of the refs
+ * module. Code outside of the refs module should use only the public
+ * functions defined in "refs.h", and should *not* include this file.
+ */
+
+/*
+ * Flag passed to lock_ref_sha1_basic() telling it to tolerate broken
+ * refs (i.e., because the reference is about to be deleted anyway).
+ */
+#define REF_DELETING	0x02
+
+/*
+ * Used as a flag in ref_update::flags when a loose ref is being
+ * pruned.
+ */
+#define REF_ISPRUNING	0x04
+
+/*
+ * Used as a flag in ref_update::flags when the reference should be
+ * updated to new_sha1.
+ */
+#define REF_HAVE_NEW	0x08
+
+/*
+ * Used as a flag in ref_update::flags when old_sha1 should be
+ * checked.
+ */
+#define REF_HAVE_OLD	0x10
+
+/*
+ * Used as a flag in ref_update::flags when the lockfile needs to be
+ * committed.
+ */
+#define REF_NEEDS_COMMIT 0x20
+
+/*
+ * 0x40 is REF_FORCE_CREATE_REFLOG, so skip it if you're adding a
+ * value to ref_update::flags
+ */
+
+/*
+ * Return true iff refname is minimally safe. "Safe" here means that
+ * deleting a loose reference by this name will not do any damage, for
+ * example by causing a file that is not a reference to be deleted.
+ * This function does not check that the reference name is legal; for
+ * that, use check_refname_format().
+ *
+ * We consider a refname that starts with "refs/" to be safe as long
+ * as any ".." components that it might contain do not escape "refs/".
+ * Names that do not start with "refs/" are considered safe iff they
+ * consist entirely of upper case characters and '_' (like "HEAD" and
+ * "MERGE_HEAD" but not "config" or "FOO/BAR").
+ */
+int refname_is_safe(const char *refname);
+
+enum peel_status {
+	/* object was peeled successfully: */
+	PEEL_PEELED = 0,
+
+	/*
+	 * object cannot be peeled because the named object (or an
+	 * object referred to by a tag in the peel chain), does not
+	 * exist.
+	 */
+	PEEL_INVALID = -1,
+
+	/* object cannot be peeled because it is not a tag: */
+	PEEL_NON_TAG = -2,
+
+	/* ref_entry contains no peeled value because it is a symref: */
+	PEEL_IS_SYMREF = -3,
+
+	/*
+	 * ref_entry cannot be peeled because it is broken (i.e., the
+	 * symbolic reference cannot even be resolved to an object
+	 * name):
+	 */
+	PEEL_BROKEN = -4
+};
+
+/*
+ * Peel the named object; i.e., if the object is a tag, resolve the
+ * tag recursively until a non-tag is found.  If successful, store the
+ * result to sha1 and return PEEL_PEELED.  If the object is not a tag
+ * or is not valid, return PEEL_NON_TAG or PEEL_INVALID, respectively,
+ * and leave sha1 unchanged.
+ */
+enum peel_status peel_object(const unsigned char *name, unsigned char *sha1);
+
+/*
+ * Return 0 if a reference named refname could be created without
+ * conflicting with the name of an existing reference. Otherwise,
+ * return a negative value and write an explanation to err. If extras
+ * is non-NULL, it is a list of additional refnames with which refname
+ * is not allowed to conflict. If skip is non-NULL, ignore potential
+ * conflicts with refs in skip (e.g., because they are scheduled for
+ * deletion in the same operation). Behavior is undefined if the same
+ * name is listed in both extras and skip.
+ *
+ * Two reference names conflict if one of them exactly matches the
+ * leading components of the other; e.g., "foo/bar" conflicts with
+ * both "foo" and with "foo/bar/baz" but not with "foo/bar" or
+ * "foo/barbados".
+ *
+ * extras and skip must be sorted.
+ */
+int verify_refname_available(const char *newname,
+			     struct string_list *extras,
+			     struct string_list *skip,
+			     struct strbuf *err);
+
+/*
+ * Copy the reflog message msg to buf, which has been allocated sufficiently
+ * large, while cleaning up the whitespaces.  Especially, convert LF to space,
+ * because reflog file is one line per entry.
+ */
+int copy_reflog_msg(char *buf, const char *msg);
+
+int should_autocreate_reflog(const char *refname);
+
+/**
+ * Information needed for a single ref update. Set new_sha1 to the new
+ * value or to null_sha1 to delete the ref. To check the old value
+ * while the ref is locked, set (flags & REF_HAVE_OLD) and set
+ * old_sha1 to the old value, or to null_sha1 to ensure the ref does
+ * not exist before update.
+ */
+struct ref_update {
+	/*
+	 * If (flags & REF_HAVE_NEW), set the reference to this value:
+	 */
+	unsigned char new_sha1[20];
+	/*
+	 * If (flags & REF_HAVE_OLD), check that the reference
+	 * previously had this value:
+	 */
+	unsigned char old_sha1[20];
+	/*
+	 * One or more of REF_HAVE_NEW, REF_HAVE_OLD, REF_NODEREF,
+	 * REF_DELETING, and REF_ISPRUNING:
+	 */
+	unsigned int flags;
+	struct ref_lock *lock;
+	int type;
+	char *msg;
+	const char refname[FLEX_ARRAY];
+};
+
+/*
+ * Transaction states.
+ * OPEN:   The transaction is in a valid state and can accept new updates.
+ *         An OPEN transaction can be committed.
+ * CLOSED: A closed transaction is no longer active and no other operations
+ *         than free can be used on it in this state.
+ *         A transaction can either become closed by successfully committing
+ *         an active transaction or if there is a failure while building
+ *         the transaction thus rendering it failed/inactive.
+ */
+enum ref_transaction_state {
+	REF_TRANSACTION_OPEN   = 0,
+	REF_TRANSACTION_CLOSED = 1
+};
+
+/*
+ * Data structure for holding a reference transaction, which can
+ * consist of checks and updates to multiple references, carried out
+ * as atomically as possible.  This structure is opaque to callers.
+ */
+struct ref_transaction {
+	struct ref_update **updates;
+	size_t alloc;
+	size_t nr;
+	enum ref_transaction_state state;
+};
+
+#endif /* REFS_REFS_INTERNAL_H */
-- 
2.6.2

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v8 08/10] initdb: make safe_create_dir public
  2015-11-10 11:42 [PATCH v8 00/10] refs backend pre-vtable Michael Haggerty
                   ` (5 preceding siblings ...)
  2015-11-10 11:42 ` [PATCH v8 06/10] refs/refs-internal.h: new header file Michael Haggerty
@ 2015-11-10 11:42 ` Michael Haggerty
  2015-11-10 11:42 ` [PATCH v8 09/10] files_log_ref_write: new function Michael Haggerty
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Michael Haggerty @ 2015-11-10 11:42 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Jeff King, David Turner, Lukas Fleischer, Ronnie Sahlberg,
	Ramsay Jones, git, Michael Haggerty

From: David Turner <dturner@twopensource.com>

Soon we will want to create initdb functions for ref backends, and
code from initdb that calls this function needs to move into the files
backend. So this function needs to be public.

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>
---
 builtin/init-db.c | 12 ------------
 cache.h           |  8 ++++++++
 path.c            | 12 ++++++++++++
 3 files changed, 20 insertions(+), 12 deletions(-)

diff --git a/builtin/init-db.c b/builtin/init-db.c
index f59f407..07229d6 100644
--- a/builtin/init-db.c
+++ b/builtin/init-db.c
@@ -24,18 +24,6 @@ static int init_shared_repository = -1;
 static const char *init_db_template_dir;
 static const char *git_link;
 
-static void safe_create_dir(const char *dir, int share)
-{
-	if (mkdir(dir, 0777) < 0) {
-		if (errno != EEXIST) {
-			perror(dir);
-			exit(1);
-		}
-	}
-	else if (share && adjust_shared_perm(dir))
-		die(_("Could not make %s writable by group"), dir);
-}
-
 static void copy_templates_1(struct strbuf *path, struct strbuf *template,
 			     DIR *dir)
 {
diff --git a/cache.h b/cache.h
index 9a905a8..0f9808c 100644
--- a/cache.h
+++ b/cache.h
@@ -1737,4 +1737,12 @@ void stat_validity_update(struct stat_validity *sv, int fd);
 int versioncmp(const char *s1, const char *s2);
 void sleep_millisec(int millisec);
 
+/*
+ * Create a directory and (if share is nonzero) adjust its permissions
+ * according to the shared_repository setting. Only use this for
+ * directories under $GIT_DIR.  Don't use it for working tree
+ * directories.
+ */
+void safe_create_dir(const char *dir, int share);
+
 #endif /* CACHE_H */
diff --git a/path.c b/path.c
index 212695a..9e0283c 100644
--- a/path.c
+++ b/path.c
@@ -723,6 +723,18 @@ int adjust_shared_perm(const char *path)
 	return 0;
 }
 
+void safe_create_dir(const char *dir, int share)
+{
+	if (mkdir(dir, 0777) < 0) {
+		if (errno != EEXIST) {
+			perror(dir);
+			exit(1);
+		}
+	}
+	else if (share && adjust_shared_perm(dir))
+		die(_("Could not make %s writable by group"), dir);
+}
+
 static int have_same_root(const char *path1, const char *path2)
 {
 	int is_abs1, is_abs2;
-- 
2.6.2

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v8 09/10] files_log_ref_write: new function
  2015-11-10 11:42 [PATCH v8 00/10] refs backend pre-vtable Michael Haggerty
                   ` (6 preceding siblings ...)
  2015-11-10 11:42 ` [PATCH v8 08/10] initdb: make safe_create_dir public Michael Haggerty
@ 2015-11-10 11:42 ` Michael Haggerty
  2015-11-10 11:42 ` [PATCH v8 10/10] refs: break out ref conflict checks Michael Haggerty
  2015-11-16 18:51 ` [PATCH v8 00/10] refs backend pre-vtable David Turner
  9 siblings, 0 replies; 13+ messages in thread
From: Michael Haggerty @ 2015-11-10 11:42 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Jeff King, David Turner, Lukas Fleischer, Ronnie Sahlberg,
	Ramsay Jones, git, Michael Haggerty

From: David Turner <dturner@twopensource.com>

Because HEAD and stash are per-worktree, every refs backend needs to
go through the files backend to write these refs.

So create a new function, files_log_ref_write, and add it to
refs/refs-internal.h. Later, we will use this to handle reflog updates
for per-worktree symbolic refs (HEAD).

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/files-backend.c | 8 ++++++++
 refs/refs-internal.h | 4 ++++
 2 files changed, 12 insertions(+)

diff --git a/refs/files-backend.c b/refs/files-backend.c
index 14ec506..aaf2639 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -2734,6 +2734,14 @@ static int log_ref_write(const char *refname, const unsigned char *old_sha1,
 			 const unsigned char *new_sha1, const char *msg,
 			 int flags, struct strbuf *err)
 {
+	return files_log_ref_write(refname, old_sha1, new_sha1, msg, flags,
+				   err);
+}
+
+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)
+{
 	struct strbuf sb = STRBUF_INIT;
 	int ret = log_ref_write_1(refname, old_sha1, new_sha1, msg, &sb, flags,
 				  err);
diff --git a/refs/refs-internal.h b/refs/refs-internal.h
index 9077c11..7b6c8bc 100644
--- a/refs/refs-internal.h
+++ b/refs/refs-internal.h
@@ -177,4 +177,8 @@ struct ref_transaction {
 	enum ref_transaction_state state;
 };
 
+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);
+
 #endif /* REFS_REFS_INTERNAL_H */
-- 
2.6.2

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v8 10/10] refs: break out ref conflict checks
  2015-11-10 11:42 [PATCH v8 00/10] refs backend pre-vtable Michael Haggerty
                   ` (7 preceding siblings ...)
  2015-11-10 11:42 ` [PATCH v8 09/10] files_log_ref_write: new function Michael Haggerty
@ 2015-11-10 11:42 ` Michael Haggerty
  2015-11-16 18:51 ` [PATCH v8 00/10] refs backend pre-vtable David Turner
  9 siblings, 0 replies; 13+ messages in thread
From: Michael Haggerty @ 2015-11-10 11:42 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Jeff King, David Turner, Lukas Fleischer, Ronnie Sahlberg,
	Ramsay Jones, git, Michael Haggerty

From: David Turner <dturner@twopensource.com>

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

Also move rename_ref_available 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.c               | 44 ++++++++++++++++++++++++++++++++++++++++++++
 refs/files-backend.c | 49 +++++++------------------------------------------
 refs/refs-internal.h | 16 ++++++++++++++++
 3 files changed, 67 insertions(+), 42 deletions(-)

diff --git a/refs.c b/refs.c
index 1620a53..ad883ec 100644
--- a/refs.c
+++ b/refs.c
@@ -1029,3 +1029,47 @@ int ref_is_hidden(const char *refname)
 	}
 	return 0;
 }
+
+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 at the place where dirname would be inserted into
+	 * extras. If there is an entry at that position that starts
+	 * with dirname (remember, dirname includes the trailing
+	 * slash) and is not in skip, then we have a conflict.
+	 */
+	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/files-backend.c b/refs/files-backend.c
index aaf2639..4db3e36 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -728,6 +728,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;
@@ -833,32 +834,12 @@ 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;
-			}
-		}
-	}
-
-	/* No conflicts were found */
-	ret = 0;
+	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;
 
 cleanup:
 	strbuf_release(&dirname);
@@ -2473,22 +2454,6 @@ int verify_refname_available(const char *newname,
 	return 0;
 }
 
-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/refs-internal.h b/refs/refs-internal.h
index 7b6c8bc..c7dded3 100644
--- a/refs/refs-internal.h
+++ b/refs/refs-internal.h
@@ -181,4 +181,20 @@ 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/foo/"). 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. Either one
+ * can be NULL, signifying the empty list.
+ */
+const char *find_descendant_ref(const char *dirname,
+				const struct string_list *extras,
+				const struct string_list *skip);
+
+int rename_ref_available(const char *oldname, const char *newname);
+
 #endif /* REFS_REFS_INTERNAL_H */
-- 
2.6.2

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH v8 00/10] refs backend pre-vtable
  2015-11-10 11:42 [PATCH v8 00/10] refs backend pre-vtable Michael Haggerty
                   ` (8 preceding siblings ...)
  2015-11-10 11:42 ` [PATCH v8 10/10] refs: break out ref conflict checks Michael Haggerty
@ 2015-11-16 18:51 ` David Turner
  2015-11-19 14:58   ` Jeff King
  9 siblings, 1 reply; 13+ messages in thread
From: David Turner @ 2015-11-16 18:51 UTC (permalink / raw)
  To: Michael Haggerty
  Cc: Junio C Hamano, Jeff King, Lukas Fleischer, Ronnie Sahlberg,
	Ramsay Jones, git

On Tue, 2015-11-10 at 12:42 +0100, Michael Haggerty wrote:
> Another re-roll of this patch series, to address the comments of
> Ramsay Jones (thanks!) about v7 [1].
> 
> This version has the following changes compared to v7:
> 
> * Drop "refs: make is_branch public" patch. This was already done
>   quite a while ago:
> 
>       e7e0f26 refs.c: add a public is_branch function (2014-07-15)
> 
> * Instead of having refs-internal.h include refs.h, have the "*.c"
>   files include both header files.
> 
> * Remove some unneeded includes from refs/files-backend.c.
> 
> Since patch 01/11 of v7 was omitted, the patches in this version are
> numbered differently. In particular, it is now patches 01 through 07
> that form the core of this patch series. The last three patches can
> easily be postponed if that will speed the progress of the first
> seven.
> 
> These patches are also available from my GitHub fork [2] as branch
> "refs-backend-pre-vtable".

This version looks good to me.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v8 00/10] refs backend pre-vtable
  2015-11-16 18:51 ` [PATCH v8 00/10] refs backend pre-vtable David Turner
@ 2015-11-19 14:58   ` Jeff King
  2015-11-20  6:34     ` Michael Haggerty
  0 siblings, 1 reply; 13+ messages in thread
From: Jeff King @ 2015-11-19 14:58 UTC (permalink / raw)
  To: David Turner
  Cc: Michael Haggerty, Junio C Hamano, Lukas Fleischer,
	Ronnie Sahlberg, Ramsay Jones, git

On Mon, Nov 16, 2015 at 01:51:08PM -0500, David Turner wrote:

> > Since patch 01/11 of v7 was omitted, the patches in this version are
> > numbered differently. In particular, it is now patches 01 through 07
> > that form the core of this patch series. The last three patches can
> > easily be postponed if that will speed the progress of the first
> > seven.
> > 
> > These patches are also available from my GitHub fork [2] as branch
> > "refs-backend-pre-vtable".
> 
> This version looks good to me.

Thanks. Looks like patch 7 didn't make it to the list due to its size. I
picked it up from Michael's GitHub fork.

Just so I'm sure, this is replacing all of what Junio had queued in
dt/refs-backend-pre-vtable, right?

-Peff

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v8 00/10] refs backend pre-vtable
  2015-11-19 14:58   ` Jeff King
@ 2015-11-20  6:34     ` Michael Haggerty
  0 siblings, 0 replies; 13+ messages in thread
From: Michael Haggerty @ 2015-11-20  6:34 UTC (permalink / raw)
  To: Jeff King, David Turner
  Cc: Junio C Hamano, Lukas Fleischer, Ronnie Sahlberg, Ramsay Jones,
	git

On November 19, 2015 3:58:48 PM GMT+01:00, Jeff King <peff@peff.net> wrote:
> [...]
>Thanks. Looks like patch 7 didn't make it to the list due to its size.
>I picked it up from Michael's GitHub fork.

Oh, thanks. I hadn't noticed the problem.

>Just so I'm sure, this is replacing all of what Junio had queued in
>dt/refs-backend-pre-vtable, right?

That is correct.

Michael

Sent from a cellphone. Sorry for any screwed-up formatting. See below.
-- 
Sent from my Android device with K-9 Mail. Please excuse my brevity.

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2015-11-20  6:35 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-11-10 11:42 [PATCH v8 00/10] refs backend pre-vtable Michael Haggerty
2015-11-10 11:42 ` [PATCH v8 01/10] verify_refname_available(): rename function Michael Haggerty
2015-11-10 11:42 ` [PATCH v8 02/10] verify_refname_available(): new function Michael Haggerty
2015-11-10 11:42 ` [PATCH v8 03/10] copy_msg(): rename to copy_reflog_msg() Michael Haggerty
2015-11-10 11:42 ` [PATCH v8 04/10] pack_if_possible_fn(): use ref_type() instead of is_per_worktree_ref() Michael Haggerty
2015-11-10 11:42 ` [PATCH v8 05/10] refname_is_safe(): improve docstring Michael Haggerty
2015-11-10 11:42 ` [PATCH v8 06/10] refs/refs-internal.h: new header file Michael Haggerty
2015-11-10 11:42 ` [PATCH v8 08/10] initdb: make safe_create_dir public Michael Haggerty
2015-11-10 11:42 ` [PATCH v8 09/10] files_log_ref_write: new function Michael Haggerty
2015-11-10 11:42 ` [PATCH v8 10/10] refs: break out ref conflict checks Michael Haggerty
2015-11-16 18:51 ` [PATCH v8 00/10] refs backend pre-vtable David Turner
2015-11-19 14:58   ` Jeff King
2015-11-20  6:34     ` Michael Haggerty

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).