From: mhagger@alum.mit.edu
To: Junio C Hamano <gitster@pobox.com>
Cc: git@vger.kernel.org, Jeff King <peff@peff.net>,
Drew Northup <drew.northup@maine.edu>,
Jakub Narebski <jnareb@gmail.com>,
Heiko Voigt <hvoigt@hvoigt.net>,
Johan Herland <johan@herland.net>,
Julian Phillips <julian@quantumfyre.co.uk>,
Michael Haggerty <mhagger@alum.mit.edu>
Subject: [PATCH v2 24/51] refs.c: reorder definitions more logically
Date: Mon, 12 Dec 2011 06:38:31 +0100 [thread overview]
Message-ID: <1323668338-1764-25-git-send-email-mhagger@alum.mit.edu> (raw)
In-Reply-To: <1323668338-1764-1-git-send-email-mhagger@alum.mit.edu>
From: Michael Haggerty <mhagger@alum.mit.edu>
Reorder definitions in file: first check_refname_format() and helper
functions, then the functions for managing the ref_entry and ref_array
data structures, then ref_cache, then the more "business-logicky"
stuff. No code is changed.
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
refs.c | 655 ++++++++++++++++++++++++++++++++--------------------------------
1 files changed, 329 insertions(+), 326 deletions(-)
diff --git a/refs.c b/refs.c
index 064a70f..3cc3e4f 100644
--- a/refs.c
+++ b/refs.c
@@ -4,6 +4,108 @@
#include "tag.h"
#include "dir.h"
+/*
+ * Make sure "ref" is something reasonable to have under ".git/refs/";
+ * We do not like it if:
+ *
+ * - any path component of it begins with ".", or
+ * - it has double dots "..", or
+ * - it has ASCII control character, "~", "^", ":" or SP, anywhere, or
+ * - it ends with a "/".
+ * - it ends with ".lock"
+ * - it contains a "\" (backslash)
+ */
+
+/* Return true iff ch is not allowed in reference names. */
+static inline int bad_ref_char(int ch)
+{
+ if (((unsigned) ch) <= ' ' || ch == 0x7f ||
+ ch == '~' || ch == '^' || ch == ':' || ch == '\\')
+ return 1;
+ /* 2.13 Pattern Matching Notation */
+ if (ch == '*' || ch == '?' || ch == '[') /* Unsupported */
+ return 1;
+ return 0;
+}
+
+/*
+ * 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.
+ */
+static int check_refname_component(const char *refname, int flags)
+{
+ const char *cp;
+ char last = '\0';
+
+ for (cp = refname; ; cp++) {
+ char ch = *cp;
+ if (ch == '\0' || ch == '/')
+ break;
+ if (bad_ref_char(ch))
+ return -1; /* Illegal character in refname. */
+ if (last == '.' && ch == '.')
+ return -1; /* Refname contains "..". */
+ if (last == '@' && ch == '{')
+ return -1; /* Refname contains "@{". */
+ last = ch;
+ }
+ if (cp == refname)
+ return -1; /* Component has zero length. */
+ if (refname[0] == '.') {
+ if (!(flags & REFNAME_DOT_COMPONENT))
+ return -1; /* Component starts with '.'. */
+ /*
+ * Even if leading dots are allowed, don't allow "."
+ * as a component (".." is prevented by a rule above).
+ */
+ if (refname[1] == '\0')
+ return -1; /* Component equals ".". */
+ }
+ if (cp - refname >= 5 && !memcmp(cp - 5, ".lock", 5))
+ return -1; /* Refname ends with ".lock". */
+ return cp - refname;
+}
+
+int check_refname_format(const char *refname, int flags)
+{
+ int component_len, component_count = 0;
+
+ while (1) {
+ /* We are at the start of a path component. */
+ component_len = check_refname_component(refname, flags);
+ if (component_len < 0) {
+ if ((flags & REFNAME_REFSPEC_PATTERN) &&
+ refname[0] == '*' &&
+ (refname[1] == '\0' || refname[1] == '/')) {
+ /* Accept one wildcard as a full refname component. */
+ flags &= ~REFNAME_REFSPEC_PATTERN;
+ component_len = 1;
+ } else {
+ return -1;
+ }
+ }
+ component_count++;
+ if (refname[component_len] == '\0')
+ break;
+ /* Skip to next component. */
+ refname += component_len + 1;
+ }
+
+ if (refname[component_len - 1] == '.')
+ return -1; /* Refname ends with '.'. */
+ if (!(flags & REFNAME_ALLOW_ONELEVEL) && component_count < 2)
+ return -1; /* Refname has only one component. */
+ return 0;
+}
+
+struct ref_entry;
+
+struct ref_array {
+ int nr, alloc;
+ struct ref_entry **refs;
+};
+
/* ISSYMREF=0x01, ISPACKED=0x02 and ISBROKEN=0x04 are public interfaces */
#define REF_KNOWS_PEELED 0x10
@@ -15,44 +117,6 @@ struct ref_entry {
char name[FLEX_ARRAY];
};
-struct ref_array {
- int nr, alloc;
- struct ref_entry **refs;
-};
-
-/*
- * Parse one line from a packed-refs file. Write the SHA1 to sha1.
- * Return a pointer to the refname within the line (null-terminated),
- * or NULL if there was a problem.
- */
-static const char *parse_ref_line(char *line, unsigned char *sha1)
-{
- /*
- * 42: the answer to everything.
- *
- * In this case, it happens to be the answer to
- * 40 (length of sha1 hex representation)
- * +1 (space in between hex and name)
- * +1 (newline at the end of the line)
- */
- int len = strlen(line) - 42;
-
- if (len <= 0)
- return NULL;
- if (get_sha1_hex(line, sha1) < 0)
- return NULL;
- if (!isspace(line[40]))
- return NULL;
- line += 41;
- if (isspace(*line))
- return NULL;
- if (line[len] != '\n')
- return NULL;
- line[len] = 0;
-
- return line;
-}
-
static struct ref_entry *create_ref_entry(const char *refname,
const unsigned char *sha1, int flag,
int check_name)
@@ -79,6 +143,16 @@ static void add_ref(struct ref_array *refs, struct ref_entry *ref)
refs->refs[refs->nr++] = ref;
}
+static void clear_ref_array(struct ref_array *array)
+{
+ int i;
+ for (i = 0; i < array->nr; i++)
+ free(array->refs[i]);
+ free(array->refs);
+ array->nr = array->alloc = 0;
+ array->refs = NULL;
+}
+
static int ref_entry_cmp(const void *a, const void *b)
{
struct ref_entry *one = *(struct ref_entry **)a;
@@ -86,6 +160,31 @@ static int ref_entry_cmp(const void *a, const void *b)
return strcmp(one->name, two->name);
}
+static struct ref_entry *search_ref_array(struct ref_array *array, const char *refname)
+{
+ struct ref_entry *e, **r;
+ int len;
+
+ if (refname == NULL)
+ return NULL;
+
+ if (!array->nr)
+ return NULL;
+
+ len = strlen(refname) + 1;
+ e = xmalloc(sizeof(struct ref_entry) + len);
+ memcpy(e->name, refname, len);
+
+ r = bsearch(&e, array->refs, array->nr, sizeof(*array->refs), ref_entry_cmp);
+
+ free(e);
+
+ if (r == NULL)
+ return NULL;
+
+ return *r;
+}
+
/*
* Emit a warning and return true iff ref1 and ref2 have the same name
* and the same sha1. Die if they have the same name but different
@@ -127,29 +226,137 @@ static void sort_ref_array(struct ref_array *array)
array->nr = i + 1;
}
-static struct ref_entry *search_ref_array(struct ref_array *array, const char *refname)
+#define DO_FOR_EACH_INCLUDE_BROKEN 01
+
+static struct ref_entry *current_ref;
+
+static int do_one_ref(const char *base, each_ref_fn fn, int trim,
+ int flags, void *cb_data, struct ref_entry *entry)
{
- struct ref_entry *e, **r;
- int len;
+ if (prefixcmp(entry->name, base))
+ return 0;
- if (refname == NULL)
- return NULL;
+ if (!(flags & DO_FOR_EACH_INCLUDE_BROKEN)) {
+ if (entry->flag & REF_ISBROKEN)
+ return 0; /* ignore broken refs e.g. dangling symref */
+ if (!has_sha1_file(entry->sha1)) {
+ error("%s does not point to a valid object!", entry->name);
+ return 0;
+ }
+ }
+ current_ref = entry;
+ return fn(entry->name + trim, entry->sha1, entry->flag, cb_data);
+}
- if (!array->nr)
- return NULL;
+static int do_for_each_ref_in_array(struct ref_array *array, int offset,
+ const char *base,
+ each_ref_fn fn, int trim, int flags, void *cb_data)
+{
+ int i;
+ for (i = offset; i < array->nr; i++) {
+ int retval = do_one_ref(base, fn, trim, flags, cb_data, array->refs[i]);
+ if (retval)
+ return retval;
+ }
+ return 0;
+}
- len = strlen(refname) + 1;
- e = xmalloc(sizeof(struct ref_entry) + len);
- memcpy(e->name, refname, len);
+static int do_for_each_ref_in_arrays(struct ref_array *array1,
+ struct ref_array *array2,
+ const char *base, each_ref_fn fn, int trim,
+ int flags, void *cb_data)
+{
+ int retval;
+ int i1 = 0, i2 = 0;
- r = bsearch(&e, array->refs, array->nr, sizeof(*array->refs), ref_entry_cmp);
+ while (1) {
+ struct ref_entry *e1, *e2;
+ int cmp;
+ if (i1 == array1->nr) {
+ return do_for_each_ref_in_array(array2, i2,
+ base, fn, trim, flags, cb_data);
+ }
+ if (i2 == array2->nr) {
+ return do_for_each_ref_in_array(array1, i1,
+ base, fn, trim, flags, cb_data);
+ }
+ e1 = array1->refs[i1];
+ e2 = array2->refs[i2];
+ cmp = strcmp(e1->name, e2->name);
+ if (cmp == 0) {
+ /* Two refs with the same name; ignore the one from array1. */
+ i1++;
+ continue;
+ }
+ if (cmp < 0) {
+ retval = do_one_ref(base, fn, trim, flags, cb_data, e1);
+ i1++;
+ } else {
+ retval = do_one_ref(base, fn, trim, flags, cb_data, e2);
+ i2++;
+ }
+ if (retval)
+ return retval;
+ }
+}
- free(e);
+/*
+ * Return true iff refname1 and refname2 conflict with each other.
+ * 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".
+ */
+static int names_conflict(const char *refname1, const char *refname2)
+{
+ for (; *refname1 && *refname1 == *refname2; refname1++, refname2++)
+ ;
+ return (*refname1 == '\0' && *refname2 == '/')
+ || (*refname1 == '/' && *refname2 == '\0');
+}
- if (r == NULL)
- return NULL;
+struct name_conflict_cb {
+ const char *refname;
+ const char *oldrefname;
+ const char *conflicting_refname;
+};
- return *r;
+static int name_conflict_fn(const char *existingrefname, const unsigned char *sha1,
+ int flags, void *cb_data)
+{
+ struct name_conflict_cb *data = (struct name_conflict_cb *)cb_data;
+ if (data->oldrefname && !strcmp(data->oldrefname, existingrefname))
+ return 0;
+ if (names_conflict(data->refname, existingrefname)) {
+ data->conflicting_refname = existingrefname;
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * Return true iff a reference named refname could be created without
+ * conflicting with the name of an existing reference. If oldrefname
+ * is non-NULL, ignore potential conflicts with oldrefname (e.g.,
+ * because oldrefname is scheduled for deletion in the same
+ * operation).
+ */
+static int is_refname_available(const char *refname, const char *oldrefname,
+ struct ref_array *array)
+{
+ struct name_conflict_cb data;
+ data.refname = refname;
+ data.oldrefname = oldrefname;
+ data.conflicting_refname = NULL;
+
+ if (do_for_each_ref_in_array(array, 0, "", name_conflict_fn,
+ 0, DO_FOR_EACH_INCLUDE_BROKEN,
+ &data)) {
+ error("'%s' exists; cannot create '%s'",
+ data.conflicting_refname, refname);
+ return 0;
+ }
+ return 1;
}
/*
@@ -166,20 +373,8 @@ static struct ref_cache {
char name[FLEX_ARRAY];
} *ref_cache;
-static struct ref_entry *current_ref;
-
static struct ref_array extra_refs;
-static void clear_ref_array(struct ref_array *array)
-{
- int i;
- for (i = 0; i < array->nr; i++)
- free(array->refs[i]);
- free(array->refs);
- array->nr = array->alloc = 0;
- array->refs = NULL;
-}
-
static void clear_packed_ref_cache(struct ref_cache *refs)
{
if (refs->did_packed)
@@ -236,6 +431,39 @@ void invalidate_ref_cache(const char *submodule)
clear_loose_ref_cache(refs);
}
+/*
+ * Parse one line from a packed-refs file. Write the SHA1 to sha1.
+ * Return a pointer to the refname within the line (null-terminated),
+ * or NULL if there was a problem.
+ */
+static const char *parse_ref_line(char *line, unsigned char *sha1)
+{
+ /*
+ * 42: the answer to everything.
+ *
+ * In this case, it happens to be the answer to
+ * 40 (length of sha1 hex representation)
+ * +1 (space in between hex and name)
+ * +1 (newline at the end of the line)
+ */
+ int len = strlen(line) - 42;
+
+ if (len <= 0)
+ return NULL;
+ if (get_sha1_hex(line, sha1) < 0)
+ return NULL;
+ if (!isspace(line[40]))
+ return NULL;
+ line += 41;
+ if (isspace(*line))
+ return NULL;
+ if (line[len] != '\n')
+ return NULL;
+ line[len] = 0;
+
+ return line;
+}
+
static void read_packed_refs(FILE *f, struct ref_array *array)
{
struct ref_entry *last = NULL;
@@ -357,47 +585,13 @@ static void get_ref_dir(struct ref_cache *refs, const char *base,
}
} else if (read_ref_full(refname, sha1, 1, &flag)) {
hashclr(sha1);
- flag |= REF_ISBROKEN;
- }
- add_ref(array, create_ref_entry(refname, sha1, flag, 1));
- }
- free(refname);
- closedir(dir);
- }
-}
-
-struct warn_if_dangling_data {
- FILE *fp;
- const char *refname;
- const char *msg_fmt;
-};
-
-static int warn_if_dangling_symref(const char *refname, const unsigned char *sha1,
- int flags, void *cb_data)
-{
- struct warn_if_dangling_data *d = cb_data;
- const char *resolves_to;
- unsigned char junk[20];
-
- if (!(flags & REF_ISSYMREF))
- return 0;
-
- resolves_to = resolve_ref(refname, junk, 0, NULL);
- if (!resolves_to || strcmp(resolves_to, d->refname))
- return 0;
-
- fprintf(d->fp, d->msg_fmt, refname);
- return 0;
-}
-
-void warn_dangling_symref(FILE *fp, const char *msg_fmt, const char *refname)
-{
- struct warn_if_dangling_data data;
-
- data.fp = fp;
- data.refname = refname;
- data.msg_fmt = msg_fmt;
- for_each_rawref(warn_if_dangling_symref, &data);
+ flag |= REF_ISBROKEN;
+ }
+ add_ref(array, create_ref_entry(refname, sha1, flag, 1));
+ }
+ free(refname);
+ closedir(dir);
+ }
}
static struct ref_array *get_loose_refs(struct ref_cache *refs)
@@ -632,23 +826,10 @@ int read_ref(const char *refname, unsigned char *sha1)
return read_ref_full(refname, sha1, 1, NULL);
}
-#define DO_FOR_EACH_INCLUDE_BROKEN 01
-static int do_one_ref(const char *base, each_ref_fn fn, int trim,
- int flags, void *cb_data, struct ref_entry *entry)
+int ref_exists(const char *refname)
{
- if (prefixcmp(entry->name, base))
- return 0;
-
- if (!(flags & DO_FOR_EACH_INCLUDE_BROKEN)) {
- if (entry->flag & REF_ISBROKEN)
- return 0; /* ignore broken refs e.g. dangling symref */
- if (!has_sha1_file(entry->sha1)) {
- error("%s does not point to a valid object!", entry->name);
- return 0;
- }
- }
- current_ref = entry;
- return fn(entry->name + trim, entry->sha1, entry->flag, cb_data);
+ unsigned char sha1[20];
+ return !!resolve_ref(refname, sha1, 1, NULL);
}
static int filter_refs(const char *refname, const unsigned char *sha1, int flags,
@@ -701,56 +882,38 @@ fallback:
return -1;
}
-static int do_for_each_ref_in_array(struct ref_array *array, int offset,
- const char *base,
- each_ref_fn fn, int trim, int flags, void *cb_data)
+struct warn_if_dangling_data {
+ FILE *fp;
+ const char *refname;
+ const char *msg_fmt;
+};
+
+static int warn_if_dangling_symref(const char *refname, const unsigned char *sha1,
+ int flags, void *cb_data)
{
- int i;
- for (i = offset; i < array->nr; i++) {
- int retval = do_one_ref(base, fn, trim, flags, cb_data, array->refs[i]);
- if (retval)
- return retval;
- }
+ struct warn_if_dangling_data *d = cb_data;
+ const char *resolves_to;
+ unsigned char junk[20];
+
+ if (!(flags & REF_ISSYMREF))
+ return 0;
+
+ resolves_to = resolve_ref(refname, junk, 0, NULL);
+ if (!resolves_to || strcmp(resolves_to, d->refname))
+ return 0;
+
+ fprintf(d->fp, d->msg_fmt, refname);
return 0;
}
-static int do_for_each_ref_in_arrays(struct ref_array *array1,
- struct ref_array *array2,
- const char *base, each_ref_fn fn, int trim,
- int flags, void *cb_data)
+void warn_dangling_symref(FILE *fp, const char *msg_fmt, const char *refname)
{
- int retval;
- int i1 = 0, i2 = 0;
+ struct warn_if_dangling_data data;
- while (1) {
- struct ref_entry *e1, *e2;
- int cmp;
- if (i1 == array1->nr) {
- return do_for_each_ref_in_array(array2, i2,
- base, fn, trim, flags, cb_data);
- }
- if (i2 == array2->nr) {
- return do_for_each_ref_in_array(array1, i1,
- base, fn, trim, flags, cb_data);
- }
- e1 = array1->refs[i1];
- e2 = array2->refs[i2];
- cmp = strcmp(e1->name, e2->name);
- if (cmp == 0) {
- /* Two refs with the same name; ignore the one from array1. */
- i1++;
- continue;
- }
- if (cmp < 0) {
- retval = do_one_ref(base, fn, trim, flags, cb_data, e1);
- i1++;
- } else {
- retval = do_one_ref(base, fn, trim, flags, cb_data, e2);
- i2++;
- }
- if (retval)
- return retval;
- }
+ data.fp = fp;
+ data.refname = refname;
+ data.msg_fmt = msg_fmt;
+ for_each_rawref(warn_if_dangling_symref, &data);
}
static int do_for_each_ref(const char *submodule, const char *base, each_ref_fn fn,
@@ -921,101 +1084,6 @@ int for_each_rawref(each_ref_fn fn, void *cb_data)
DO_FOR_EACH_INCLUDE_BROKEN, cb_data);
}
-/*
- * Make sure "ref" is something reasonable to have under ".git/refs/";
- * We do not like it if:
- *
- * - any path component of it begins with ".", or
- * - it has double dots "..", or
- * - it has ASCII control character, "~", "^", ":" or SP, anywhere, or
- * - it ends with a "/".
- * - it ends with ".lock"
- * - it contains a "\" (backslash)
- */
-
-/* Return true iff ch is not allowed in reference names. */
-static inline int bad_ref_char(int ch)
-{
- if (((unsigned) ch) <= ' ' || ch == 0x7f ||
- ch == '~' || ch == '^' || ch == ':' || ch == '\\')
- return 1;
- /* 2.13 Pattern Matching Notation */
- if (ch == '*' || ch == '?' || ch == '[') /* Unsupported */
- return 1;
- return 0;
-}
-
-/*
- * 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.
- */
-static int check_refname_component(const char *refname, int flags)
-{
- const char *cp;
- char last = '\0';
-
- for (cp = refname; ; cp++) {
- char ch = *cp;
- if (ch == '\0' || ch == '/')
- break;
- if (bad_ref_char(ch))
- return -1; /* Illegal character in refname. */
- if (last == '.' && ch == '.')
- return -1; /* Refname contains "..". */
- if (last == '@' && ch == '{')
- return -1; /* Refname contains "@{". */
- last = ch;
- }
- if (cp == refname)
- return -1; /* Component has zero length. */
- if (refname[0] == '.') {
- if (!(flags & REFNAME_DOT_COMPONENT))
- return -1; /* Component starts with '.'. */
- /*
- * Even if leading dots are allowed, don't allow "."
- * as a component (".." is prevented by a rule above).
- */
- if (refname[1] == '\0')
- return -1; /* Component equals ".". */
- }
- if (cp - refname >= 5 && !memcmp(cp - 5, ".lock", 5))
- return -1; /* Refname ends with ".lock". */
- return cp - refname;
-}
-
-int check_refname_format(const char *refname, int flags)
-{
- int component_len, component_count = 0;
-
- while (1) {
- /* We are at the start of a path component. */
- component_len = check_refname_component(refname, flags);
- if (component_len < 0) {
- if ((flags & REFNAME_REFSPEC_PATTERN) &&
- refname[0] == '*' &&
- (refname[1] == '\0' || refname[1] == '/')) {
- /* Accept one wildcard as a full refname component. */
- flags &= ~REFNAME_REFSPEC_PATTERN;
- component_len = 1;
- } else {
- return -1;
- }
- }
- component_count++;
- if (refname[component_len] == '\0')
- break;
- /* Skip to next component. */
- refname += component_len + 1;
- }
-
- if (refname[component_len - 1] == '.')
- return -1; /* Refname ends with '.'. */
- if (!(flags & REFNAME_ALLOW_ONELEVEL) && component_count < 2)
- return -1; /* Refname has only one component. */
- return 0;
-}
-
const char *prettify_refname(const char *name)
{
return name + (
@@ -1086,65 +1154,6 @@ static int remove_empty_directories(const char *file)
}
/*
- * Return true iff refname1 and refname2 conflict with each other.
- * 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".
- */
-static int names_conflict(const char *refname1, const char *refname2)
-{
- for (; *refname1 && *refname1 == *refname2; refname1++, refname2++)
- ;
- return (*refname1 == '\0' && *refname2 == '/')
- || (*refname1 == '/' && *refname2 == '\0');
-}
-
-struct name_conflict_cb {
- const char *refname;
- const char *oldrefname;
- const char *conflicting_refname;
-};
-
-static int name_conflict_fn(const char *existingrefname, const unsigned char *sha1,
- int flags, void *cb_data)
-{
- struct name_conflict_cb *data = (struct name_conflict_cb *)cb_data;
- if (data->oldrefname && !strcmp(data->oldrefname, existingrefname))
- return 0;
- if (names_conflict(data->refname, existingrefname)) {
- data->conflicting_refname = existingrefname;
- return 1;
- }
- return 0;
-}
-
-/*
- * Return true iff a reference named refname could be created without
- * conflicting with the name of an existing reference. If oldrefname
- * is non-NULL, ignore potential conflicts with oldrefname (e.g.,
- * because oldrefname is scheduled for deletion in the same
- * operation).
- */
-static int is_refname_available(const char *refname, const char *oldrefname,
- struct ref_array *array)
-{
- struct name_conflict_cb data;
- data.refname = refname;
- data.oldrefname = oldrefname;
- data.conflicting_refname = NULL;
-
- if (do_for_each_ref_in_array(array, 0, "", name_conflict_fn,
- 0, DO_FOR_EACH_INCLUDE_BROKEN,
- &data)) {
- error("'%s' exists; cannot create '%s'",
- data.conflicting_refname, refname);
- return 0;
- }
- return 1;
-}
-
-/*
* *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.
@@ -2057,12 +2066,6 @@ int update_ref(const char *action, const char *refname,
return 0;
}
-int ref_exists(const char *refname)
-{
- unsigned char sha1[20];
- return !!resolve_ref(refname, sha1, 1, NULL);
-}
-
struct ref *find_ref_by_name(const struct ref *list, const char *name)
{
for ( ; list; list = list->next)
--
1.7.8
next prev parent reply other threads:[~2011-12-12 5:41 UTC|newest]
Thread overview: 79+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-12-12 5:38 [PATCH v2 00/51] ref-api-C and ref-api-D re-roll mhagger
2011-12-12 5:38 ` [PATCH v2 01/51] struct ref_entry: document name member mhagger
2011-12-12 5:38 ` [PATCH v2 02/51] refs: rename "refname" variables mhagger
2011-12-13 0:37 ` Junio C Hamano
2011-12-12 5:38 ` [PATCH v2 03/51] refs: rename parameters result -> sha1 mhagger
2011-12-12 5:38 ` [PATCH v2 04/51] clear_ref_array(): rename from free_ref_array() mhagger
2011-12-12 5:38 ` [PATCH v2 05/51] is_refname_available(): remove the "quiet" argument mhagger
2011-12-12 5:38 ` [PATCH v2 06/51] parse_ref_line(): add docstring mhagger
2011-12-12 5:38 ` [PATCH v2 07/51] add_ref(): " mhagger
2011-12-12 5:38 ` [PATCH v2 08/51] is_dup_ref(): extract function from sort_ref_array() mhagger
2011-12-12 8:33 ` Jeff King
2011-12-12 11:44 ` Michael Haggerty
2011-12-12 17:14 ` Junio C Hamano
2011-12-12 22:33 ` Junio C Hamano
2011-12-13 4:35 ` Michael Haggerty
2011-12-13 5:00 ` Michael Haggerty
2011-12-12 5:38 ` [PATCH v2 09/51] refs: change signatures of get_packed_refs() and get_loose_refs() mhagger
2011-12-12 5:38 ` [PATCH v2 10/51] get_ref_dir(): change signature mhagger
2011-12-12 5:38 ` [PATCH v2 11/51] resolve_gitlink_ref(): improve docstring mhagger
2011-12-12 5:38 ` [PATCH v2 12/51] Pass a (ref_cache *) to the resolve_gitlink_*() helper functions mhagger
2011-12-12 5:38 ` [PATCH v2 13/51] resolve_gitlink_ref_recursive(): change to work with struct ref_cache mhagger
2011-12-12 5:38 ` [PATCH v2 14/51] repack_without_ref(): remove temporary mhagger
2011-12-12 5:38 ` [PATCH v2 15/51] create_ref_entry(): extract function from add_ref() mhagger
2011-12-12 5:38 ` [PATCH v2 16/51] add_ref(): take a (struct ref_entry *) parameter mhagger
2011-12-12 5:38 ` [PATCH v2 17/51] do_for_each_ref(): correctly terminate while processesing extra_refs mhagger
2011-12-12 22:41 ` Junio C Hamano
2011-12-12 5:38 ` [PATCH v2 18/51] do_for_each_ref_in_array(): new function mhagger
2011-12-12 5:38 ` [PATCH v2 19/51] do_for_each_ref_in_arrays(): " mhagger
2011-12-12 5:38 ` [PATCH v2 20/51] repack_without_ref(): reimplement using do_for_each_ref_in_array() mhagger
2011-12-12 22:44 ` Junio C Hamano
2011-12-12 5:38 ` [PATCH v2 21/51] names_conflict(): new function, extracted from is_refname_available() mhagger
2011-12-12 5:38 ` [PATCH v2 22/51] names_conflict(): simplify implementation mhagger
2011-12-12 5:38 ` [PATCH v2 23/51] is_refname_available(): reimplement using do_for_each_ref_in_array() mhagger
2011-12-12 5:38 ` mhagger [this message]
2011-12-12 5:38 ` [PATCH v2 25/51] free_ref_entry(): new function mhagger
2011-12-12 5:38 ` [PATCH v2 26/51] check_refname_component(): return 0 for zero-length components mhagger
2011-12-12 5:38 ` [PATCH v2 27/51] struct ref_entry: nest the value part in a union mhagger
2011-12-12 5:38 ` [PATCH v2 28/51] refs.c: rename ref_array -> ref_dir mhagger
2011-12-13 0:45 ` Junio C Hamano
2011-12-13 5:43 ` Michael Haggerty
2011-12-13 6:37 ` Junio C Hamano
2011-12-13 19:12 ` Michael Haggerty
2011-12-13 19:17 ` Junio C Hamano
2011-12-13 22:13 ` Michael Haggerty
2011-12-13 23:24 ` Junio C Hamano
2011-12-14 0:19 ` Junio C Hamano
2011-12-14 2:33 ` Jeff King
2011-12-15 8:19 ` Michael Haggerty
2011-12-15 8:37 ` Jeff King
2012-01-17 15:07 ` Michael Haggerty
2012-02-10 14:51 ` Michael Haggerty
2012-02-10 20:44 ` Jeff King
2012-02-10 21:17 ` Junio C Hamano
2012-02-11 6:33 ` Michael Haggerty
2011-12-12 5:38 ` [PATCH v2 29/51] refs: store references hierarchically mhagger
2011-12-12 5:38 ` [PATCH v2 30/51] sort_ref_dir(): do not sort if already sorted mhagger
2011-12-12 23:26 ` Junio C Hamano
2011-12-12 5:38 ` [PATCH v2 31/51] refs: sort ref_dirs lazily mhagger
2011-12-12 5:38 ` [PATCH v2 32/51] do_for_each_ref(): only iterate over the subtree that was requested mhagger
2011-12-12 5:38 ` [PATCH v2 33/51] get_ref_dir(): keep track of the current ref_dir mhagger
2011-12-12 5:38 ` [PATCH v2 34/51] refs: wrap top-level ref_dirs in ref_entries mhagger
2011-12-12 5:38 ` [PATCH v2 35/51] get_packed_refs(): return (ref_entry *) instead of (ref_dir *) mhagger
2011-12-12 5:38 ` [PATCH v2 36/51] get_loose_refs(): " mhagger
2011-12-12 5:38 ` [PATCH v2 37/51] is_refname_available(): take " mhagger
2011-12-12 5:38 ` [PATCH v2 38/51] find_ref(): " mhagger
2011-12-12 5:38 ` [PATCH v2 39/51] read_packed_refs(): " mhagger
2011-12-12 5:38 ` [PATCH v2 40/51] add_ref(): " mhagger
2011-12-12 5:38 ` [PATCH v2 41/51] find_containing_direntry(): use " mhagger
2011-12-12 5:38 ` [PATCH v2 42/51] search_ref_dir(): take " mhagger
2011-12-12 5:38 ` [PATCH v2 43/51] add_entry(): " mhagger
2011-12-12 5:38 ` [PATCH v2 44/51] do_for_each_ref_in_dir*(): " mhagger
2011-12-12 5:38 ` [PATCH v2 45/51] sort_ref_dir(): " mhagger
2011-12-12 5:38 ` [PATCH v2 46/51] struct ref_dir: store a reference to the enclosing ref_cache mhagger
2011-12-12 5:38 ` [PATCH v2 47/51] read_loose_refs(): take a (ref_entry *) as argument mhagger
2011-12-12 5:38 ` [PATCH v2 48/51] refs: read loose references lazily mhagger
2011-12-12 5:38 ` [PATCH v2 49/51] is_refname_available(): query only possibly-conflicting references mhagger
2011-12-12 5:38 ` [PATCH v2 50/51] read_packed_refs(): keep track of the directory being worked in mhagger
2011-12-12 5:38 ` [PATCH v2 51/51] repack_without_ref(): call clear_packed_ref_cache() mhagger
2011-12-12 8:24 ` [PATCH v2 00/51] ref-api-C and ref-api-D re-roll 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
List information: http://vger.kernel.org/majordomo-info.html
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1323668338-1764-25-git-send-email-mhagger@alum.mit.edu \
--to=mhagger@alum.mit.edu \
--cc=drew.northup@maine.edu \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=hvoigt@hvoigt.net \
--cc=jnareb@gmail.com \
--cc=johan@herland.net \
--cc=julian@quantumfyre.co.uk \
--cc=peff@peff.net \
/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.
Code repositories for project(s) associated with this public inbox
https://80x24.org/mirrors/git.git
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 read-only IMAP folder(s) and NNTP newsgroup(s).