git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: David Turner <dturner@twopensource.com>
To: git@vger.kernel.org, mhagger@alum.mit.edu
Cc: Ronnie Sahlberg <sahlberg@google.com>,
	David Turner <dturner@twopensource.com>,
	Junio C Hamano <gitster@pobox.com>
Subject: [PATCH v5 09/26] refs.c: move dwim and friend functions to the common refs code
Date: Tue, 27 Oct 2015 22:14:10 -0400	[thread overview]
Message-ID: <1445998467-11511-10-git-send-email-dturner@twopensource.com> (raw)
In-Reply-To: <1445998467-11511-1-git-send-email-dturner@twopensource.com>

From: Ronnie Sahlberg <sahlberg@google.com>

These functions do not contain any backend specific code so we move
them to the common code and share across all backends.

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>
---
 refs-be-files.c | 203 --------------------------------------------------------
 refs.c          | 203 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 203 insertions(+), 203 deletions(-)

diff --git a/refs-be-files.c b/refs-be-files.c
index 8be8405..b74b6cc 100644
--- a/refs-be-files.c
+++ b/refs-be-files.c
@@ -2247,30 +2247,6 @@ const char *prettify_refname(const char *name)
 		0);
 }
 
-static const char *ref_rev_parse_rules[] = {
-	"%.*s",
-	"refs/%.*s",
-	"refs/tags/%.*s",
-	"refs/heads/%.*s",
-	"refs/remotes/%.*s",
-	"refs/remotes/%.*s/HEAD",
-	NULL
-};
-
-int refname_match(const char *abbrev_name, const char *full_name)
-{
-	const char **p;
-	const int abbrev_name_len = strlen(abbrev_name);
-
-	for (p = ref_rev_parse_rules; *p; p++) {
-		if (!strcmp(full_name, mkpath(*p, abbrev_name_len, abbrev_name))) {
-			return 1;
-		}
-	}
-
-	return 0;
-}
-
 static void unlock_ref(struct ref_lock *lock)
 {
 	/* Do not free lock->lk -- atexit() still looks at them */
@@ -2323,92 +2299,6 @@ static int remove_empty_directories(struct strbuf *path)
 }
 
 /*
- * *string and *len will only be substituted, and *string returned (for
- * later free()ing) if the string passed in is a magic short-hand form
- * to name a branch.
- */
-static char *substitute_branch_name(const char **string, int *len)
-{
-	struct strbuf buf = STRBUF_INIT;
-	int ret = interpret_branch_name(*string, *len, &buf);
-
-	if (ret == *len) {
-		size_t size;
-		*string = strbuf_detach(&buf, &size);
-		*len = size;
-		return (char *)*string;
-	}
-
-	return NULL;
-}
-
-int dwim_ref(const char *str, int len, unsigned char *sha1, char **ref)
-{
-	char *last_branch = substitute_branch_name(&str, &len);
-	const char **p, *r;
-	int refs_found = 0;
-
-	*ref = NULL;
-	for (p = ref_rev_parse_rules; *p; p++) {
-		char fullref[PATH_MAX];
-		unsigned char sha1_from_ref[20];
-		unsigned char *this_result;
-		int flag;
-
-		this_result = refs_found ? sha1_from_ref : sha1;
-		mksnpath(fullref, sizeof(fullref), *p, len, str);
-		r = resolve_ref_unsafe(fullref, RESOLVE_REF_READING,
-				       this_result, &flag);
-		if (r) {
-			if (!refs_found++)
-				*ref = xstrdup(r);
-			if (!warn_ambiguous_refs)
-				break;
-		} else if ((flag & REF_ISSYMREF) && strcmp(fullref, "HEAD")) {
-			warning("ignoring dangling symref %s.", fullref);
-		} else if ((flag & REF_ISBROKEN) && strchr(fullref, '/')) {
-			warning("ignoring broken ref %s.", fullref);
-		}
-	}
-	free(last_branch);
-	return refs_found;
-}
-
-int dwim_log(const char *str, int len, unsigned char *sha1, char **log)
-{
-	char *last_branch = substitute_branch_name(&str, &len);
-	const char **p;
-	int logs_found = 0;
-
-	*log = NULL;
-	for (p = ref_rev_parse_rules; *p; p++) {
-		unsigned char hash[20];
-		char path[PATH_MAX];
-		const char *ref, *it;
-
-		mksnpath(path, sizeof(path), *p, len, str);
-		ref = resolve_ref_unsafe(path, RESOLVE_REF_READING,
-					 hash, NULL);
-		if (!ref)
-			continue;
-		if (reflog_exists(path))
-			it = path;
-		else if (strcmp(ref, path) && reflog_exists(ref))
-			it = ref;
-		else
-			continue;
-		if (!logs_found++) {
-			*log = xstrdup(it);
-			hashcpy(sha1, hash);
-		}
-		if (!warn_ambiguous_refs)
-			break;
-	}
-	free(last_branch);
-	return logs_found;
-}
-
-/*
  * Locks a ref returning the lock on success and NULL on failure.
  * On failure errno is set to something meaningful.
  */
@@ -4121,99 +4011,6 @@ cleanup:
 	return ret;
 }
 
-char *shorten_unambiguous_ref(const char *refname, int strict)
-{
-	int i;
-	static char **scanf_fmts;
-	static int nr_rules;
-	char *short_name;
-
-	if (!nr_rules) {
-		/*
-		 * Pre-generate scanf formats from ref_rev_parse_rules[].
-		 * Generate a format suitable for scanf from a
-		 * ref_rev_parse_rules rule by interpolating "%s" at the
-		 * location of the "%.*s".
-		 */
-		size_t total_len = 0;
-		size_t offset = 0;
-
-		/* the rule list is NULL terminated, count them first */
-		for (nr_rules = 0; ref_rev_parse_rules[nr_rules]; nr_rules++)
-			/* -2 for strlen("%.*s") - strlen("%s"); +1 for NUL */
-			total_len += strlen(ref_rev_parse_rules[nr_rules]) - 2 + 1;
-
-		scanf_fmts = xmalloc(nr_rules * sizeof(char *) + total_len);
-
-		offset = 0;
-		for (i = 0; i < nr_rules; i++) {
-			assert(offset < total_len);
-			scanf_fmts[i] = (char *)&scanf_fmts[nr_rules] + offset;
-			offset += snprintf(scanf_fmts[i], total_len - offset,
-					   ref_rev_parse_rules[i], 2, "%s") + 1;
-		}
-	}
-
-	/* bail out if there are no rules */
-	if (!nr_rules)
-		return xstrdup(refname);
-
-	/* buffer for scanf result, at most refname must fit */
-	short_name = xstrdup(refname);
-
-	/* skip first rule, it will always match */
-	for (i = nr_rules - 1; i > 0 ; --i) {
-		int j;
-		int rules_to_fail = i;
-		int short_name_len;
-
-		if (1 != sscanf(refname, scanf_fmts[i], short_name))
-			continue;
-
-		short_name_len = strlen(short_name);
-
-		/*
-		 * in strict mode, all (except the matched one) rules
-		 * must fail to resolve to a valid non-ambiguous ref
-		 */
-		if (strict)
-			rules_to_fail = nr_rules;
-
-		/*
-		 * check if the short name resolves to a valid ref,
-		 * but use only rules prior to the matched one
-		 */
-		for (j = 0; j < rules_to_fail; j++) {
-			const char *rule = ref_rev_parse_rules[j];
-			char refname[PATH_MAX];
-
-			/* skip matched rule */
-			if (i == j)
-				continue;
-
-			/*
-			 * the short name is ambiguous, if it resolves
-			 * (with this previous rule) to a valid ref
-			 * read_ref() returns 0 on success
-			 */
-			mksnpath(refname, sizeof(refname),
-				 rule, short_name_len, short_name);
-			if (ref_exists(refname))
-				break;
-		}
-
-		/*
-		 * short name is non-ambiguous if all previous rules
-		 * haven't resolved to a valid ref
-		 */
-		if (j == rules_to_fail)
-			return short_name;
-	}
-
-	free(short_name);
-	return xstrdup(refname);
-}
-
 struct expire_reflog_cb {
 	unsigned int flags;
 	reflog_expiry_should_prune_fn *should_prune_fn;
diff --git a/refs.c b/refs.c
index 071784c..e0bc031 100644
--- a/refs.c
+++ b/refs.c
@@ -342,3 +342,206 @@ int ref_is_hidden(const char *refname)
 	}
 	return 0;
 }
+
+static const char *ref_rev_parse_rules[] = {
+	"%.*s",
+	"refs/%.*s",
+	"refs/tags/%.*s",
+	"refs/heads/%.*s",
+	"refs/remotes/%.*s",
+	"refs/remotes/%.*s/HEAD",
+	NULL
+};
+
+int refname_match(const char *abbrev_name, const char *full_name)
+{
+	const char **p;
+	const int abbrev_name_len = strlen(abbrev_name);
+
+	for (p = ref_rev_parse_rules; *p; p++) {
+		if (!strcmp(full_name, mkpath(*p, abbrev_name_len, abbrev_name))) {
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
+/*
+ * *string and *len will only be substituted, and *string returned (for
+ * later free()ing) if the string passed in is a magic short-hand form
+ * to name a branch.
+ */
+static char *substitute_branch_name(const char **string, int *len)
+{
+	struct strbuf buf = STRBUF_INIT;
+	int ret = interpret_branch_name(*string, *len, &buf);
+
+	if (ret == *len) {
+		size_t size;
+		*string = strbuf_detach(&buf, &size);
+		*len = size;
+		return (char *)*string;
+	}
+
+	return NULL;
+}
+
+int dwim_ref(const char *str, int len, unsigned char *sha1, char **ref)
+{
+	char *last_branch = substitute_branch_name(&str, &len);
+	const char **p, *r;
+	int refs_found = 0;
+
+	*ref = NULL;
+	for (p = ref_rev_parse_rules; *p; p++) {
+		char fullref[PATH_MAX];
+		unsigned char sha1_from_ref[20];
+		unsigned char *this_result;
+		int flag;
+
+		this_result = refs_found ? sha1_from_ref : sha1;
+		mksnpath(fullref, sizeof(fullref), *p, len, str);
+		r = resolve_ref_unsafe(fullref, RESOLVE_REF_READING,
+				       this_result, &flag);
+		if (r) {
+			if (!refs_found++)
+				*ref = xstrdup(r);
+			if (!warn_ambiguous_refs)
+				break;
+		} else if ((flag & REF_ISSYMREF) && strcmp(fullref, "HEAD")) {
+			warning("ignoring dangling symref %s.", fullref);
+		} else if ((flag & REF_ISBROKEN) && strchr(fullref, '/')) {
+			warning("ignoring broken ref %s.", fullref);
+		}
+	}
+	free(last_branch);
+	return refs_found;
+}
+
+int dwim_log(const char *str, int len, unsigned char *sha1, char **log)
+{
+	char *last_branch = substitute_branch_name(&str, &len);
+	const char **p;
+	int logs_found = 0;
+
+	*log = NULL;
+	for (p = ref_rev_parse_rules; *p; p++) {
+		unsigned char hash[20];
+		char path[PATH_MAX];
+		const char *ref, *it;
+
+		mksnpath(path, sizeof(path), *p, len, str);
+		ref = resolve_ref_unsafe(path, RESOLVE_REF_READING,
+					 hash, NULL);
+		if (!ref)
+			continue;
+		if (reflog_exists(path))
+			it = path;
+		else if (strcmp(ref, path) && reflog_exists(ref))
+			it = ref;
+		else
+			continue;
+		if (!logs_found++) {
+			*log = xstrdup(it);
+			hashcpy(sha1, hash);
+		}
+		if (!warn_ambiguous_refs)
+			break;
+	}
+	free(last_branch);
+	return logs_found;
+}
+
+char *shorten_unambiguous_ref(const char *refname, int strict)
+{
+	int i;
+	static char **scanf_fmts;
+	static int nr_rules;
+	char *short_name;
+
+	if (!nr_rules) {
+		/*
+		 * Pre-generate scanf formats from ref_rev_parse_rules[].
+		 * Generate a format suitable for scanf from a
+		 * ref_rev_parse_rules rule by interpolating "%s" at the
+		 * location of the "%.*s".
+		 */
+		size_t total_len = 0;
+		size_t offset = 0;
+
+		/* the rule list is NULL terminated, count them first */
+		for (nr_rules = 0; ref_rev_parse_rules[nr_rules]; nr_rules++)
+			/* -2 for strlen("%.*s") - strlen("%s"); +1 for NUL */
+			total_len += strlen(ref_rev_parse_rules[nr_rules]) - 2 + 1;
+
+		scanf_fmts = xmalloc(nr_rules * sizeof(char *) + total_len);
+
+		offset = 0;
+		for (i = 0; i < nr_rules; i++) {
+			assert(offset < total_len);
+			scanf_fmts[i] = (char *)&scanf_fmts[nr_rules] + offset;
+			offset += snprintf(scanf_fmts[i], total_len - offset,
+					   ref_rev_parse_rules[i], 2, "%s") + 1;
+		}
+	}
+
+	/* bail out if there are no rules */
+	if (!nr_rules)
+		return xstrdup(refname);
+
+	/* buffer for scanf result, at most refname must fit */
+	short_name = xstrdup(refname);
+
+	/* skip first rule, it will always match */
+	for (i = nr_rules - 1; i > 0 ; --i) {
+		int j;
+		int rules_to_fail = i;
+		int short_name_len;
+
+		if (1 != sscanf(refname, scanf_fmts[i], short_name))
+			continue;
+
+		short_name_len = strlen(short_name);
+
+		/*
+		 * in strict mode, all (except the matched one) rules
+		 * must fail to resolve to a valid non-ambiguous ref
+		 */
+		if (strict)
+			rules_to_fail = nr_rules;
+
+		/*
+		 * check if the short name resolves to a valid ref,
+		 * but use only rules prior to the matched one
+		 */
+		for (j = 0; j < rules_to_fail; j++) {
+			const char *rule = ref_rev_parse_rules[j];
+			char refname[PATH_MAX];
+
+			/* skip matched rule */
+			if (i == j)
+				continue;
+
+			/*
+			 * the short name is ambiguous, if it resolves
+			 * (with this previous rule) to a valid ref
+			 * read_ref() returns 0 on success
+			 */
+			mksnpath(refname, sizeof(refname),
+				 rule, short_name_len, short_name);
+			if (ref_exists(refname))
+				break;
+		}
+
+		/*
+		 * short name is non-ambiguous if all previous rules
+		 * haven't resolved to a valid ref
+		 */
+		if (j == rules_to_fail)
+			return short_name;
+	}
+
+	free(short_name);
+	return xstrdup(refname);
+}
-- 
2.4.2.658.g6d8523e-twtrsrc

  parent reply	other threads:[~2015-10-28  2:15 UTC|newest]

Thread overview: 67+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-10-28  2:14 [PATCH v5 00/26] refs backend pre-vtable David Turner
2015-10-28  2:14 ` [PATCH v5 01/26] refs.c: create a public version of verify_refname_available David Turner
2015-10-28  2:14 ` [PATCH v5 02/26] refs: make is_branch public David Turner
2015-10-28  2:14 ` [PATCH v5 03/26] refs-be-files.c: rename refs to refs-be-files David Turner
2015-10-28  2:14 ` [PATCH v5 04/26] refs.c: add a new refs.c file to hold all common refs code David Turner
2015-10-28  2:14 ` [PATCH v5 05/26] refs.c: move update_ref to refs.c David Turner
2015-10-28  2:14 ` [PATCH v5 06/26] refs.c: move delete_pseudoref and delete_ref to the common code David Turner
2015-10-28  2:14 ` [PATCH v5 07/26] refs.c: move read_ref_at to the common refs file David Turner
2015-10-28  2:14 ` [PATCH v5 08/26] refs.c: move the hidden refs functions to the common code David Turner
2015-10-28  2:14 ` David Turner [this message]
2015-10-28  2:14 ` [PATCH v5 10/26] refs.c: move warn_if_dangling_symref* " David Turner
2015-10-28  2:14 ` [PATCH v5 11/26] refs.c: move read_ref, read_ref_full and ref_exists " David Turner
2015-10-28  2:14 ` [PATCH v5 12/26] refs.c: move resolve_refdup to common David Turner
2015-10-28  2:14 ` [PATCH v5 13/26] refs.c: move check_refname_format to the common code David Turner
2015-10-28  2:14 ` [PATCH v5 14/26] refs.c: move is_branch " David Turner
2015-10-28  2:14 ` [PATCH v5 15/26] refs.c: move prettify_refname " David Turner
2015-10-28  2:14 ` [PATCH v5 16/26] refs.c: move ref iterators " David Turner
2015-11-01  4:39   ` Michael Haggerty
2015-10-28  2:14 ` [PATCH v5 17/26] refs.c: move head_ref_namespaced " David Turner
2015-10-28  2:14 ` [PATCH v5 18/26] refs: move transaction functions into " David Turner
2015-11-01  8:17   ` Michael Haggerty
2015-11-02 22:19     ` David Turner
2015-10-28  2:14 ` [PATCH v5 19/26] refs.c: move refname_is_safe to the " David Turner
2015-10-28  2:14 ` [PATCH v5 20/26] refs.c: move copy_msg " David Turner
2015-10-28  2:14 ` [PATCH v5 21/26] refs.c: move peel_object " David Turner
2015-10-28  2:14 ` [PATCH v5 22/26] refs.c: move should_autocreate_reflog to " David Turner
2015-10-28  2:14 ` [PATCH v5 23/26] initdb: move safe_create_dir into " David Turner
2015-10-28  2:14 ` [PATCH v5 24/26] refs: make files_log_ref_write functions public David Turner
2015-10-28  2:14 ` [PATCH v5 25/26] refs: break out ref conflict checks David Turner
2015-11-02 16:52   ` Michael Haggerty
2015-10-28  2:14 ` [PATCH v5 26/26] introduce "extensions" form of core.repositoryformatversion David Turner
2015-11-03  7:36 ` [PATCH v5 00/26] refs backend pre-vtable Michael Haggerty
2015-11-03  7:39 ` [PATCH v6 00/25] " Michael Haggerty
2015-11-03  7:39   ` [PATCH v6 01/25] refs: make is_branch public Michael Haggerty
2015-11-03  7:39   ` [PATCH v6 02/25] refs/files-backend.c: new file, renamed from refs.c Michael Haggerty
2015-11-03  7:39   ` [PATCH v6 03/25] refs: add a new file, refs/refs.c, to hold common refs code Michael Haggerty
2015-11-03  7:39   ` [PATCH v6 04/25] refs: move update_ref to refs/refs.c Michael Haggerty
2015-11-03  7:39   ` [PATCH v6 05/25] refs: move delete_pseudoref and delete_ref to the common code Michael Haggerty
2015-11-03  7:39   ` [PATCH v6 06/25] refs: move read_ref_at to the common refs file Michael Haggerty
2015-11-03  7:39   ` [PATCH v6 07/25] refs: move the hidden refs functions to the common code Michael Haggerty
2015-11-03  7:39   ` [PATCH v6 08/25] refs: move dwim and friend functions to the common refs code Michael Haggerty
2015-11-03  7:39   ` [PATCH v6 09/25] refs: move warn_if_dangling_symref* to the common code Michael Haggerty
2015-11-03  7:39   ` [PATCH v6 10/25] refs: move read_ref, read_ref_full and ref_exists " Michael Haggerty
2015-11-03  7:39   ` [PATCH v6 11/25] refs: move resolve_refdup to common Michael Haggerty
2015-11-03  7:39   ` [PATCH v6 12/25] refs: move check_refname_format to the common code Michael Haggerty
2015-11-03  7:39   ` [PATCH v6 13/25] refs: move is_branch " Michael Haggerty
2015-11-03  7:39   ` [PATCH v6 14/25] refs: move prettify_refname " Michael Haggerty
2015-11-03  7:39   ` [PATCH v6 15/25] refs: move ref iterators " Michael Haggerty
2015-11-03  7:40   ` [PATCH v6 16/25] refs: move head_ref_namespaced " Michael Haggerty
2015-11-03  7:40   ` [PATCH v6 17/25] refs: move transaction functions " Michael Haggerty
2015-11-03  7:40   ` [PATCH v6 18/25] refs: move refname_is_safe " Michael Haggerty
2015-11-03  7:40   ` [PATCH v6 19/25] refs: move copy_msg " Michael Haggerty
2015-11-03  7:40   ` [PATCH v6 20/25] refs: move peel_object " Michael Haggerty
2015-11-03  7:40   ` [PATCH v6 21/25] refs: move should_autocreate_reflog to " Michael Haggerty
2015-11-03  7:40   ` [PATCH v6 22/25] initdb: make safe_create_dir public Michael Haggerty
2015-11-03  7:40   ` [PATCH v6 23/25] files_log_ref_write: new function Michael Haggerty
2015-11-03  7:40   ` [PATCH v6 24/25] refs: create a shared version of verify_refname_available Michael Haggerty
2015-11-03  7:40   ` [PATCH v6 25/25] refs: break out ref conflict checks Michael Haggerty
2015-11-04 21:01     ` David Turner
2015-11-05  4:00       ` Michael Haggerty
2015-11-05 16:22         ` David Turner
2015-11-06 13:34           ` Michael Haggerty
2015-11-06 17:28             ` Junio C Hamano
2015-11-06 23:24               ` Junio C Hamano
2015-11-08  5:03                 ` Michael Haggerty
2015-11-08  5:54                   ` Michael Haggerty
2015-11-08 18:23                   ` Junio C Hamano

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1445998467-11511-10-git-send-email-dturner@twopensource.com \
    --to=dturner@twopensource.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=mhagger@alum.mit.edu \
    --cc=sahlberg@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).