* [PATCH v2 31/51] refs: sort ref_dirs lazily
From: mhagger @ 2011-12-12 5:38 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Jeff King, Drew Northup, Jakub Narebski, Heiko Voigt,
Johan Herland, Julian Phillips, Michael Haggerty
In-Reply-To: <1323668338-1764-1-git-send-email-mhagger@alum.mit.edu>
From: Michael Haggerty <mhagger@alum.mit.edu>
Sort ref_dirs lazily, when the ordering is needed: for searching via
search_ref_dir(), and when iterating over the references via
do_for_each_ref_in_dir() and do_for_each_ref_in_dirs().
This change means that we never have to sort directories recursively,
so change sort_ref_dirs() to not recurse.
NOTE: the dirs can now be sorted as a side-effect of other function
calls. Therefore, it would be problematic to do something from a
each_ref_fn callback that could provoke the sorting of the directory
that is currently being iterated over. This is not so likely, because
a directory is always sorted just before being iterated over and thus
can be searched through during the iteration without causing a
re-sort. But if a callback function would add a reference to a parent
directory of the reference in the iteration, then try to resolve a
reference under that directory, inconsistency could result.
Add a comment in refs.h warning against modifications during
iteration.
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
refs.c | 35 +++++++++++++++--------------------
refs.h | 7 +++++--
2 files changed, 20 insertions(+), 22 deletions(-)
diff --git a/refs.c b/refs.c
index ce141ea..f01da78 100644
--- a/refs.c
+++ b/refs.c
@@ -256,9 +256,14 @@ static struct ref_entry *search_ref_dir(struct ref_dir *dir, const char *refname
/*
* We need dir to be sorted so that binary search works.
- * Calling sort_ref_dir() here is not quite as terribly
- * inefficient as it looks, because directories that are
- * already sorted are not re-sorted.
+ * Calling sort_ref_dir() here is not as terribly inefficient
+ * as it looks. (1) If the directory is already sorted, it is
+ * not re-sorted. (2) When adding a reference,
+ * search_ref_dir() is only called to find the containing
+ * subdirectories; there is no search of the directory to
+ * which the reference will be stored. Thus adding a bunch of
+ * references one after the other to a single subdirectory
+ * doesn't require *any* intermediate sorting.
*/
sort_ref_dir(dir);
@@ -364,26 +369,16 @@ static int is_dup_ref(const struct ref_entry *ref1, const struct ref_entry *ref2
}
/*
- * Sort the entries in dir and its subdirectories (if they are not
- * already sorted).
+ * Sort the entries in dir (if they are not already sorted). Sort
+ * only dir itself, not its subdirectories.
*/
static void sort_ref_dir(struct ref_dir *dir)
{
int i, j;
struct ref_entry *last = NULL;
- if (dir->sorted == dir->nr) {
- /*
- * This directory is already sorted and de-duped, but
- * we still have to sort subdirectories.
- */
- for (i = 0; i < dir->nr; i++) {
- struct ref_entry *entry = dir->entries[i];
- if (entry->flag & REF_DIR)
- sort_ref_dir(&entry->u.subdir);
- }
- return;
- }
+ if (dir->sorted == dir->nr)
+ return; /* This directory is already sorted and de-duped */
qsort(dir->entries, dir->nr, sizeof(*dir->entries), ref_entry_cmp);
@@ -393,7 +388,6 @@ static void sort_ref_dir(struct ref_dir *dir)
if (last && is_dup_ref(last, entry)) {
free_ref_entry(entry);
} else if (entry->flag & REF_DIR) {
- sort_ref_dir(&entry->u.subdir);
dir->entries[i++] = entry;
last = NULL;
} else {
@@ -430,6 +424,7 @@ static int do_for_each_ref_in_dir(struct ref_dir *dir, int offset,
each_ref_fn fn, int trim, int flags, void *cb_data)
{
int i;
+ sort_ref_dir(dir);
for (i = offset; i < dir->nr; i++) {
struct ref_entry *entry = dir->entries[i];
int retval;
@@ -453,6 +448,8 @@ static int do_for_each_ref_in_dirs(struct ref_dir *dir1,
int retval;
int i1 = 0, i2 = 0;
+ sort_ref_dir(dir1);
+ sort_ref_dir(dir2);
while (1) {
struct ref_entry *e1, *e2, *entry;
int cmp;
@@ -701,7 +698,6 @@ static void read_packed_refs(FILE *f, struct ref_dir *dir)
!get_sha1_hex(refline + 1, sha1))
hashcpy(last->u.value.peeled, sha1);
}
- sort_ref_dir(dir);
}
void add_extra_ref(const char *refname, const unsigned char *sha1, int flag)
@@ -803,7 +799,6 @@ static struct ref_dir *get_loose_refs(struct ref_cache *refs)
{
if (!refs->did_loose) {
get_ref_dir(refs, "refs", &refs->loose);
- sort_ref_dir(&refs->loose);
refs->did_loose = 1;
}
return &refs->loose;
diff --git a/refs.h b/refs.h
index d498291..5bb4678 100644
--- a/refs.h
+++ b/refs.h
@@ -15,8 +15,11 @@ struct ref_lock {
#define REF_ISBROKEN 0x04
/*
- * Calls the specified function for each ref file until it returns nonzero,
- * and returns the value
+ * Calls the specified function for each ref file until it returns
+ * nonzero, and returns the value. Please note that it is not safe to
+ * modify references while an iteration is in progress, unless the
+ * same callback function invocation that modifies the reference also
+ * returns a nonzero value to immediately stop the iteration.
*/
typedef int each_ref_fn(const char *refname, const unsigned char *sha1, int flags, void *cb_data);
extern int head_ref(each_ref_fn, void *);
--
1.7.8
^ permalink raw reply related
* [PATCH v2 28/51] refs.c: rename ref_array -> ref_dir
From: mhagger @ 2011-12-12 5:38 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Jeff King, Drew Northup, Jakub Narebski, Heiko Voigt,
Johan Herland, Julian Phillips, Michael Haggerty
In-Reply-To: <1323668338-1764-1-git-send-email-mhagger@alum.mit.edu>
From: Michael Haggerty <mhagger@alum.mit.edu>
This purely textual change is in preparation for storing references
hierarchically, when the old ref_array structure will represent one
"directory" of references. Rename functions that deal with this
structure analogously, and also rename the structure's "refs" member
to "entries".
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
refs.c | 166 ++++++++++++++++++++++++++++++++--------------------------------
1 files changed, 83 insertions(+), 83 deletions(-)
diff --git a/refs.c b/refs.c
index fe6d657..b74ef80 100644
--- a/refs.c
+++ b/refs.c
@@ -106,9 +106,9 @@ struct ref_value {
unsigned char peeled[20];
};
-struct ref_array {
+struct ref_dir {
int nr, alloc;
- struct ref_entry **refs;
+ struct ref_entry **entries;
};
/* ISSYMREF=0x01, ISPACKED=0x02 and ISBROKEN=0x04 are public interfaces */
@@ -147,21 +147,21 @@ static void free_ref_entry(struct ref_entry *entry)
free(entry);
}
-/* Add a ref_entry to the end of the ref_array (unsorted). */
-static void add_ref(struct ref_array *refs, struct ref_entry *ref)
+/* Add a ref_entry to the end of the ref_dir (unsorted). */
+static void add_ref(struct ref_dir *refs, struct ref_entry *ref)
{
- ALLOC_GROW(refs->refs, refs->nr + 1, refs->alloc);
- refs->refs[refs->nr++] = ref;
+ ALLOC_GROW(refs->entries, refs->nr + 1, refs->alloc);
+ refs->entries[refs->nr++] = ref;
}
-static void clear_ref_array(struct ref_array *array)
+static void clear_ref_dir(struct ref_dir *dir)
{
int i;
- for (i = 0; i < array->nr; i++)
- free_ref_entry(array->refs[i]);
- free(array->refs);
- array->nr = array->alloc = 0;
- array->refs = NULL;
+ for (i = 0; i < dir->nr; i++)
+ free_ref_entry(dir->entries[i]);
+ free(dir->entries);
+ dir->nr = dir->alloc = 0;
+ dir->entries = NULL;
}
static int ref_entry_cmp(const void *a, const void *b)
@@ -171,7 +171,7 @@ 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)
+static struct ref_entry *search_ref_dir(struct ref_dir *dir, const char *refname)
{
struct ref_entry *e, **r;
int len;
@@ -179,14 +179,14 @@ static struct ref_entry *search_ref_array(struct ref_array *array, const char *r
if (refname == NULL)
return NULL;
- if (!array->nr)
+ if (!dir->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);
+ r = bsearch(&e, dir->entries, dir->nr, sizeof(*dir->entries), ref_entry_cmp);
free(e);
@@ -215,26 +215,26 @@ static int is_dup_ref(const struct ref_entry *ref1, const struct ref_entry *ref2
}
}
-static void sort_ref_array(struct ref_array *array)
+static void sort_ref_dir(struct ref_dir *dir)
{
int i, j;
/* Nothing to sort unless there are at least two entries */
- if (array->nr < 2)
+ if (dir->nr < 2)
return;
- qsort(array->refs, array->nr, sizeof(*array->refs), ref_entry_cmp);
+ qsort(dir->entries, dir->nr, sizeof(*dir->entries), ref_entry_cmp);
/* Remove any duplicates from the ref_array */
i = 0;
- for (j = 1; j < array->nr; j++) {
- if (is_dup_ref(array->refs[i], array->refs[j])) {
- free_ref_entry(array->refs[j]);
+ for (j = 1; j < dir->nr; j++) {
+ if (is_dup_ref(dir->entries[i], dir->entries[j])) {
+ free_ref_entry(dir->entries[j]);
continue;
}
- array->refs[++i] = array->refs[j];
+ dir->entries[++i] = dir->entries[j];
}
- array->nr = i + 1;
+ dir->nr = i + 1;
}
#define DO_FOR_EACH_INCLUDE_BROKEN 01
@@ -259,23 +259,23 @@ static int do_one_ref(const char *base, each_ref_fn fn, int trim,
return fn(entry->name + trim, entry->u.value.sha1, entry->flag, cb_data);
}
-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)
+static int do_for_each_ref_in_dir(struct ref_dir *dir, 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]);
+ for (i = offset; i < dir->nr; i++) {
+ int retval = do_one_ref(base, fn, trim, flags, cb_data, dir->entries[i]);
if (retval)
return retval;
}
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)
+static int do_for_each_ref_in_dirs(struct ref_dir *dir1,
+ struct ref_dir *dir2,
+ const char *base, each_ref_fn fn, int trim,
+ int flags, void *cb_data)
{
int retval;
int i1 = 0, i2 = 0;
@@ -283,19 +283,19 @@ static int do_for_each_ref_in_arrays(struct ref_array *array1,
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 (i1 == dir1->nr) {
+ return do_for_each_ref_in_dir(dir2, 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);
+ if (i2 == dir2->nr) {
+ return do_for_each_ref_in_dir(dir1, i1,
+ base, fn, trim, flags, cb_data);
}
- e1 = array1->refs[i1];
- e2 = array2->refs[i2];
+ e1 = dir1->entries[i1];
+ e2 = dir2->entries[i2];
cmp = strcmp(e1->name, e2->name);
if (cmp == 0) {
- /* Two refs with the same name; ignore the one from array1. */
+ /* Two refs with the same name; ignore the one from dir1. */
i1++;
continue;
}
@@ -353,16 +353,16 @@ static int name_conflict_fn(const char *existingrefname, const unsigned char *sh
* operation).
*/
static int is_refname_available(const char *refname, const char *oldrefname,
- struct ref_array *array)
+ struct ref_dir *dir)
{
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)) {
+ if (do_for_each_ref_in_dir(dir, 0, "", name_conflict_fn,
+ 0, DO_FOR_EACH_INCLUDE_BROKEN,
+ &data)) {
error("'%s' exists; cannot create '%s'",
data.conflicting_refname, refname);
return 0;
@@ -378,25 +378,25 @@ static struct ref_cache {
struct ref_cache *next;
char did_loose;
char did_packed;
- struct ref_array loose;
- struct ref_array packed;
+ struct ref_dir loose;
+ struct ref_dir packed;
/* The submodule name, or "" for the main repo. */
char name[FLEX_ARRAY];
} *ref_cache;
-static struct ref_array extra_refs;
+static struct ref_dir extra_refs;
static void clear_packed_ref_cache(struct ref_cache *refs)
{
if (refs->did_packed)
- clear_ref_array(&refs->packed);
+ clear_ref_dir(&refs->packed);
refs->did_packed = 0;
}
static void clear_loose_ref_cache(struct ref_cache *refs)
{
if (refs->did_loose)
- clear_ref_array(&refs->loose);
+ clear_ref_dir(&refs->loose);
refs->did_loose = 0;
}
@@ -475,7 +475,7 @@ static const char *parse_ref_line(char *line, unsigned char *sha1)
return line;
}
-static void read_packed_refs(FILE *f, struct ref_array *array)
+static void read_packed_refs(FILE *f, struct ref_dir *dir)
{
struct ref_entry *last = NULL;
char refline[PATH_MAX];
@@ -497,7 +497,7 @@ static void read_packed_refs(FILE *f, struct ref_array *array)
refname = parse_ref_line(refline, sha1);
if (refname) {
last = create_ref_entry(refname, sha1, flag, 1);
- add_ref(array, last);
+ add_ref(dir, last);
continue;
}
if (last &&
@@ -507,7 +507,7 @@ static void read_packed_refs(FILE *f, struct ref_array *array)
!get_sha1_hex(refline + 1, sha1))
hashcpy(last->u.value.peeled, sha1);
}
- sort_ref_array(array);
+ sort_ref_dir(dir);
}
void add_extra_ref(const char *refname, const unsigned char *sha1, int flag)
@@ -517,10 +517,10 @@ void add_extra_ref(const char *refname, const unsigned char *sha1, int flag)
void clear_extra_refs(void)
{
- clear_ref_array(&extra_refs);
+ clear_ref_dir(&extra_refs);
}
-static struct ref_array *get_packed_refs(struct ref_cache *refs)
+static struct ref_dir *get_packed_refs(struct ref_cache *refs)
{
if (!refs->did_packed) {
const char *packed_refs_file;
@@ -541,9 +541,9 @@ static struct ref_array *get_packed_refs(struct ref_cache *refs)
}
static void get_ref_dir(struct ref_cache *refs, const char *base,
- struct ref_array *array)
+ struct ref_dir *dir)
{
- DIR *dir;
+ DIR *d;
const char *path;
if (*refs->name)
@@ -552,9 +552,9 @@ static void get_ref_dir(struct ref_cache *refs, const char *base,
path = git_path("%s", base);
- dir = opendir(path);
+ d = opendir(path);
- if (dir) {
+ if (d) {
struct dirent *de;
int baselen = strlen(base);
char *refname = xmalloc(baselen + 257);
@@ -563,7 +563,7 @@ static void get_ref_dir(struct ref_cache *refs, const char *base,
if (baselen && base[baselen-1] != '/')
refname[baselen++] = '/';
- while ((de = readdir(dir)) != NULL) {
+ while ((de = readdir(d)) != NULL) {
unsigned char sha1[20];
struct stat st;
int flag;
@@ -584,7 +584,7 @@ static void get_ref_dir(struct ref_cache *refs, const char *base,
if (stat(refdir, &st) < 0)
continue;
if (S_ISDIR(st.st_mode)) {
- get_ref_dir(refs, refname, array);
+ get_ref_dir(refs, refname, dir);
continue;
}
if (*refs->name) {
@@ -598,18 +598,18 @@ static void get_ref_dir(struct ref_cache *refs, const char *base,
hashclr(sha1);
flag |= REF_ISBROKEN;
}
- add_ref(array, create_ref_entry(refname, sha1, flag, 1));
+ add_ref(dir, create_ref_entry(refname, sha1, flag, 1));
}
free(refname);
- closedir(dir);
+ closedir(d);
}
}
-static struct ref_array *get_loose_refs(struct ref_cache *refs)
+static struct ref_dir *get_loose_refs(struct ref_cache *refs)
{
if (!refs->did_loose) {
get_ref_dir(refs, "refs", &refs->loose);
- sort_ref_array(&refs->loose);
+ sort_ref_dir(&refs->loose);
refs->did_loose = 1;
}
return &refs->loose;
@@ -628,9 +628,9 @@ static int resolve_gitlink_packed_ref(struct ref_cache *refs,
const char *refname, unsigned char *sha1)
{
struct ref_entry *ref;
- struct ref_array *array = get_packed_refs(refs);
+ struct ref_dir *dir = get_packed_refs(refs);
- ref = search_ref_array(array, refname);
+ ref = search_ref_dir(dir, refname);
if (ref == NULL)
return -1;
@@ -701,8 +701,8 @@ int resolve_gitlink_ref(const char *path, const char *refname, unsigned char *sh
*/
static int get_packed_ref(const char *refname, unsigned char *sha1)
{
- struct ref_array *packed = get_packed_refs(get_ref_cache(NULL));
- struct ref_entry *entry = search_ref_array(packed, refname);
+ struct ref_dir *packed = get_packed_refs(get_ref_cache(NULL));
+ struct ref_entry *entry = search_ref_dir(packed, refname);
if (entry) {
hashcpy(sha1, entry->u.value.sha1);
return 0;
@@ -872,8 +872,8 @@ int peel_ref(const char *refname, unsigned char *sha1)
return -1;
if ((flag & REF_ISPACKED)) {
- struct ref_array *array = get_packed_refs(get_ref_cache(NULL));
- struct ref_entry *r = search_ref_array(array, refname);
+ struct ref_dir *dir = get_packed_refs(get_ref_cache(NULL));
+ struct ref_entry *r = search_ref_dir(dir, refname);
if (r != NULL && r->flag & REF_KNOWS_PEELED) {
hashcpy(sha1, r->u.value.peeled);
@@ -933,12 +933,12 @@ static int do_for_each_ref(const char *submodule, const char *base, each_ref_fn
int retval = 0;
struct ref_cache *refs = get_ref_cache(submodule);
- retval = do_for_each_ref_in_array(&extra_refs, 0,
- base, fn, trim, flags, cb_data);
+ retval = do_for_each_ref_in_dir(&extra_refs, 0,
+ base, fn, trim, flags, cb_data);
if (!retval)
- retval = do_for_each_ref_in_arrays(get_packed_refs(refs),
- get_loose_refs(refs),
- base, fn, trim, flags, cb_data);
+ retval = do_for_each_ref_in_dirs(get_packed_refs(refs),
+ get_loose_refs(refs),
+ base, fn, trim, flags, cb_data);
current_ref = NULL;
return retval;
@@ -1377,10 +1377,10 @@ static struct lock_file packlock;
static int repack_without_ref(const char *refname)
{
struct repack_without_ref_sb data;
- struct ref_array *packed;
+ struct ref_dir *packed;
packed = get_packed_refs(get_ref_cache(NULL));
- if (search_ref_array(packed, refname) == NULL)
+ if (search_ref_dir(packed, refname) == NULL)
return 0;
data.refname = refname;
data.fd = hold_lock_file_for_update(&packlock, git_path("packed-refs"), 0);
@@ -1388,7 +1388,7 @@ static int repack_without_ref(const char *refname)
unable_to_lock_error(git_path("packed-refs"), errno);
return error("cannot delete '%s' from packed refs", refname);
}
- do_for_each_ref_in_array(packed, 0, "", repack_without_ref_fn, 0, 0, &data);
+ do_for_each_ref_in_dir(packed, 0, "", repack_without_ref_fn, 0, 0, &data);
return commit_lock_file(&packlock);
}
@@ -1999,10 +1999,10 @@ int for_each_reflog_ent(const char *refname, each_reflog_ent_fn fn, void *cb_dat
static int do_for_each_reflog(const char *base, each_ref_fn fn, void *cb_data)
{
- DIR *dir = opendir(git_path("logs/%s", base));
+ DIR *d = opendir(git_path("logs/%s", base));
int retval = 0;
- if (dir) {
+ if (d) {
struct dirent *de;
int baselen = strlen(base);
char *log = xmalloc(baselen + 257);
@@ -2011,7 +2011,7 @@ static int do_for_each_reflog(const char *base, each_ref_fn fn, void *cb_data)
if (baselen && base[baselen-1] != '/')
log[baselen++] = '/';
- while ((de = readdir(dir)) != NULL) {
+ while ((de = readdir(d)) != NULL) {
struct stat st;
int namelen;
@@ -2038,7 +2038,7 @@ static int do_for_each_reflog(const char *base, each_ref_fn fn, void *cb_data)
break;
}
free(log);
- closedir(dir);
+ closedir(d);
}
else if (*base)
return errno;
--
1.7.8
^ permalink raw reply related
* [PATCH v2 24/51] refs.c: reorder definitions more logically
From: mhagger @ 2011-12-12 5:38 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Jeff King, Drew Northup, Jakub Narebski, Heiko Voigt,
Johan Herland, Julian Phillips, Michael Haggerty
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
^ permalink raw reply related
* [PATCH v2 27/51] struct ref_entry: nest the value part in a union
From: mhagger @ 2011-12-12 5:38 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Jeff King, Drew Northup, Jakub Narebski, Heiko Voigt,
Johan Herland, Julian Phillips, Michael Haggerty
In-Reply-To: <1323668338-1764-1-git-send-email-mhagger@alum.mit.edu>
From: Michael Haggerty <mhagger@alum.mit.edu>
This change is obviously silly by itself, but it is a step towards
adding a second member to the union.
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
refs.c | 32 +++++++++++++++++++-------------
1 files changed, 19 insertions(+), 13 deletions(-)
diff --git a/refs.c b/refs.c
index e29f76c..fe6d657 100644
--- a/refs.c
+++ b/refs.c
@@ -101,6 +101,11 @@ int check_refname_format(const char *refname, int flags)
struct ref_entry;
+struct ref_value {
+ unsigned char sha1[20];
+ unsigned char peeled[20];
+};
+
struct ref_array {
int nr, alloc;
struct ref_entry **refs;
@@ -111,8 +116,9 @@ struct ref_array {
struct ref_entry {
unsigned char flag; /* ISSYMREF? ISPACKED? */
- unsigned char sha1[20];
- unsigned char peeled[20];
+ union {
+ struct ref_value value;
+ } u;
/* The full name of the reference (e.g., "refs/heads/master"): */
char name[FLEX_ARRAY];
};
@@ -129,8 +135,8 @@ static struct ref_entry *create_ref_entry(const char *refname,
die("Reference has invalid format: '%s'", refname);
len = strlen(refname) + 1;
ref = xmalloc(sizeof(struct ref_entry) + len);
- hashcpy(ref->sha1, sha1);
- hashclr(ref->peeled);
+ hashcpy(ref->u.value.sha1, sha1);
+ hashclr(ref->u.value.peeled);
memcpy(ref->name, refname, len);
ref->flag = flag;
return ref;
@@ -199,7 +205,7 @@ static int is_dup_ref(const struct ref_entry *ref1, const struct ref_entry *ref2
{
if (!strcmp(ref1->name, ref2->name)) {
/* Duplicate name; make sure that the SHA1s match: */
- if (hashcmp(ref1->sha1, ref2->sha1))
+ if (hashcmp(ref1->u.value.sha1, ref2->u.value.sha1))
die("Duplicated ref, and SHA1s don't match: %s",
ref1->name);
warning("Duplicated ref: %s", ref1->name);
@@ -244,13 +250,13 @@ static int do_one_ref(const char *base, each_ref_fn fn, int trim,
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)) {
+ if (!has_sha1_file(entry->u.value.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);
+ return fn(entry->name + trim, entry->u.value.sha1, entry->flag, cb_data);
}
static int do_for_each_ref_in_array(struct ref_array *array, int offset,
@@ -499,7 +505,7 @@ static void read_packed_refs(FILE *f, struct ref_array *array)
strlen(refline) == 42 &&
refline[41] == '\n' &&
!get_sha1_hex(refline + 1, sha1))
- hashcpy(last->peeled, sha1);
+ hashcpy(last->u.value.peeled, sha1);
}
sort_ref_array(array);
}
@@ -628,7 +634,7 @@ static int resolve_gitlink_packed_ref(struct ref_cache *refs,
if (ref == NULL)
return -1;
- memcpy(sha1, ref->sha1, 20);
+ memcpy(sha1, ref->u.value.sha1, 20);
return 0;
}
@@ -698,7 +704,7 @@ static int get_packed_ref(const char *refname, unsigned char *sha1)
struct ref_array *packed = get_packed_refs(get_ref_cache(NULL));
struct ref_entry *entry = search_ref_array(packed, refname);
if (entry) {
- hashcpy(sha1, entry->sha1);
+ hashcpy(sha1, entry->u.value.sha1);
return 0;
}
return -1;
@@ -855,10 +861,10 @@ int peel_ref(const char *refname, unsigned char *sha1)
if (current_ref && (current_ref->name == refname
|| !strcmp(current_ref->name, refname))) {
if (current_ref->flag & REF_KNOWS_PEELED) {
- hashcpy(sha1, current_ref->peeled);
+ hashcpy(sha1, current_ref->u.value.peeled);
return 0;
}
- hashcpy(base, current_ref->sha1);
+ hashcpy(base, current_ref->u.value.sha1);
goto fallback;
}
@@ -870,7 +876,7 @@ int peel_ref(const char *refname, unsigned char *sha1)
struct ref_entry *r = search_ref_array(array, refname);
if (r != NULL && r->flag & REF_KNOWS_PEELED) {
- hashcpy(sha1, r->peeled);
+ hashcpy(sha1, r->u.value.peeled);
return 0;
}
}
--
1.7.8
^ permalink raw reply related
* [PATCH v2 26/51] check_refname_component(): return 0 for zero-length components
From: mhagger @ 2011-12-12 5:38 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Jeff King, Drew Northup, Jakub Narebski, Heiko Voigt,
Johan Herland, Julian Phillips, Michael Haggerty
In-Reply-To: <1323668338-1764-1-git-send-email-mhagger@alum.mit.edu>
From: Michael Haggerty <mhagger@alum.mit.edu>
Return 0 (instead of -1) for zero-length components. Move the
interpretation of zero-length components as illegal to
check_refname_format().
This will make it easier to extend check_refname_format() to also
check whether directory names are valid.
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
refs.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/refs.c b/refs.c
index 99667fc..e29f76c 100644
--- a/refs.c
+++ b/refs.c
@@ -51,7 +51,7 @@ static int check_refname_component(const char *refname, int flags)
last = ch;
}
if (cp == refname)
- return -1; /* Component has zero length. */
+ return 0; /* Component has zero length. */
if (refname[0] == '.') {
if (!(flags & REFNAME_DOT_COMPONENT))
return -1; /* Component starts with '.'. */
@@ -74,7 +74,7 @@ int check_refname_format(const char *refname, int flags)
while (1) {
/* We are at the start of a path component. */
component_len = check_refname_component(refname, flags);
- if (component_len < 0) {
+ if (component_len <= 0) {
if ((flags & REFNAME_REFSPEC_PATTERN) &&
refname[0] == '*' &&
(refname[1] == '\0' || refname[1] == '/')) {
--
1.7.8
^ permalink raw reply related
* [PATCH v2 25/51] free_ref_entry(): new function
From: mhagger @ 2011-12-12 5:38 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Jeff King, Drew Northup, Jakub Narebski, Heiko Voigt,
Johan Herland, Julian Phillips, Michael Haggerty
In-Reply-To: <1323668338-1764-1-git-send-email-mhagger@alum.mit.edu>
From: Michael Haggerty <mhagger@alum.mit.edu>
Add a function free_ref_entry(). This function will become nontrivial
when ref_entry (soon) becomes polymorphic.
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
refs.c | 9 +++++++--
1 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/refs.c b/refs.c
index 3cc3e4f..99667fc 100644
--- a/refs.c
+++ b/refs.c
@@ -136,6 +136,11 @@ static struct ref_entry *create_ref_entry(const char *refname,
return ref;
}
+static void free_ref_entry(struct ref_entry *entry)
+{
+ free(entry);
+}
+
/* Add a ref_entry to the end of the ref_array (unsorted). */
static void add_ref(struct ref_array *refs, struct ref_entry *ref)
{
@@ -147,7 +152,7 @@ static void clear_ref_array(struct ref_array *array)
{
int i;
for (i = 0; i < array->nr; i++)
- free(array->refs[i]);
+ free_ref_entry(array->refs[i]);
free(array->refs);
array->nr = array->alloc = 0;
array->refs = NULL;
@@ -218,7 +223,7 @@ static void sort_ref_array(struct ref_array *array)
i = 0;
for (j = 1; j < array->nr; j++) {
if (is_dup_ref(array->refs[i], array->refs[j])) {
- free(array->refs[j]);
+ free_ref_entry(array->refs[j]);
continue;
}
array->refs[++i] = array->refs[j];
--
1.7.8
^ permalink raw reply related
* [PATCH v2 21/51] names_conflict(): new function, extracted from is_refname_available()
From: mhagger @ 2011-12-12 5:38 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Jeff King, Drew Northup, Jakub Narebski, Heiko Voigt,
Johan Herland, Julian Phillips, Michael Haggerty
In-Reply-To: <1323668338-1764-1-git-send-email-mhagger@alum.mit.edu>
From: Michael Haggerty <mhagger@alum.mit.edu>
This costs an extra strlen() in the loop, but even that small price
will be clawed back in the next patch.
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
refs.c | 43 +++++++++++++++++++++++++++++++------------
1 files changed, 31 insertions(+), 12 deletions(-)
diff --git a/refs.c b/refs.c
index 2cdedf8..c33e94a 100644
--- a/refs.c
+++ b/refs.c
@@ -1086,6 +1086,30 @@ 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)
+{
+ int len1 = strlen(refname1);
+ int len2 = strlen(refname2);
+ int cmplen;
+ const char *lead;
+
+ if (len1 < len2) {
+ cmplen = len1;
+ lead = refname2;
+ } else {
+ cmplen = len2;
+ lead = refname1;
+ }
+ return !strncmp(refname1, refname2, cmplen) && lead[cmplen] == '/';
+}
+
+/*
* 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.,
@@ -1095,20 +1119,15 @@ static int remove_empty_directories(const char *file)
static int is_refname_available(const char *refname, const char *oldrefname,
struct ref_array *array)
{
- int i, namlen = strlen(refname); /* e.g. 'foo/bar' */
+ int i;
for (i = 0; i < array->nr; i++ ) {
struct ref_entry *entry = array->refs[i];
- /* entry->name could be 'foo' or 'foo/bar/baz' */
- if (!oldrefname || strcmp(oldrefname, entry->name)) {
- int len = strlen(entry->name);
- int cmplen = (namlen < len) ? namlen : len;
- const char *lead = (namlen < len) ? entry->name : refname;
- if (!strncmp(refname, entry->name, cmplen) &&
- lead[cmplen] == '/') {
- error("'%s' exists; cannot create '%s'",
- entry->name, refname);
- return 0;
- }
+ if (oldrefname && !strcmp(oldrefname, entry->name))
+ continue;
+ if (names_conflict(refname, entry->name)) {
+ error("'%s' exists; cannot create '%s'",
+ entry->name, refname);
+ return 0;
}
}
return 1;
--
1.7.8
^ permalink raw reply related
* [PATCH v2 16/51] add_ref(): take a (struct ref_entry *) parameter
From: mhagger @ 2011-12-12 5:38 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Jeff King, Drew Northup, Jakub Narebski, Heiko Voigt,
Johan Herland, Julian Phillips, Michael Haggerty
In-Reply-To: <1323668338-1764-1-git-send-email-mhagger@alum.mit.edu>
From: Michael Haggerty <mhagger@alum.mit.edu>
Take a pointer to the ref_entry to add to the array, rather than
creating the ref_entry within the function. This opens the way to
having multiple kinds of ref_entries.
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
refs.c | 14 +++++---------
1 files changed, 5 insertions(+), 9 deletions(-)
diff --git a/refs.c b/refs.c
index 442b87c..579e4c3 100644
--- a/refs.c
+++ b/refs.c
@@ -73,13 +73,8 @@ static struct ref_entry *create_ref_entry(const char *refname,
}
/* Add a ref_entry to the end of the ref_array (unsorted). */
-static void add_ref(const char *refname, const unsigned char *sha1,
- int flag, int check_name, struct ref_array *refs,
- struct ref_entry **new_ref)
+static void add_ref(struct ref_array *refs, struct ref_entry *ref)
{
- struct ref_entry *ref = create_ref_entry(refname, sha1, flag, check_name);
- if (new_ref)
- *new_ref = ref;
ALLOC_GROW(refs->refs, refs->nr + 1, refs->alloc);
refs->refs[refs->nr++] = ref;
}
@@ -262,7 +257,8 @@ static void read_packed_refs(FILE *f, struct ref_array *array)
refname = parse_ref_line(refline, sha1);
if (refname) {
- add_ref(refname, sha1, flag, 1, array, &last);
+ last = create_ref_entry(refname, sha1, flag, 1);
+ add_ref(array, last);
continue;
}
if (last &&
@@ -277,7 +273,7 @@ static void read_packed_refs(FILE *f, struct ref_array *array)
void add_extra_ref(const char *refname, const unsigned char *sha1, int flag)
{
- add_ref(refname, sha1, flag, 0, &extra_refs, NULL);
+ add_ref(&extra_refs, create_ref_entry(refname, sha1, flag, 0));
}
void clear_extra_refs(void)
@@ -363,7 +359,7 @@ static void get_ref_dir(struct ref_cache *refs, const char *base,
hashclr(sha1);
flag |= REF_ISBROKEN;
}
- add_ref(refname, sha1, flag, 1, array, NULL);
+ add_ref(array, create_ref_entry(refname, sha1, flag, 1));
}
free(refname);
closedir(dir);
--
1.7.8
^ permalink raw reply related
* [PATCH v2 23/51] is_refname_available(): reimplement using do_for_each_ref_in_array()
From: mhagger @ 2011-12-12 5:38 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Jeff King, Drew Northup, Jakub Narebski, Heiko Voigt,
Johan Herland, Julian Phillips, Michael Haggerty
In-Reply-To: <1323668338-1764-1-git-send-email-mhagger@alum.mit.edu>
From: Michael Haggerty <mhagger@alum.mit.edu>
This implementation will survive upcoming changes to the ref_array
data structure.
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
refs.c | 40 ++++++++++++++++++++++++++++++----------
1 files changed, 30 insertions(+), 10 deletions(-)
diff --git a/refs.c b/refs.c
index 12a70c1..064a70f 100644
--- a/refs.c
+++ b/refs.c
@@ -1100,6 +1100,25 @@ static int names_conflict(const char *refname1, const char *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
@@ -1110,16 +1129,17 @@ static int names_conflict(const char *refname1, const char *refname2)
static int is_refname_available(const char *refname, const char *oldrefname,
struct ref_array *array)
{
- int i;
- for (i = 0; i < array->nr; i++ ) {
- struct ref_entry *entry = array->refs[i];
- if (oldrefname && !strcmp(oldrefname, entry->name))
- continue;
- if (names_conflict(refname, entry->name)) {
- error("'%s' exists; cannot create '%s'",
- entry->name, refname);
- return 0;
- }
+ 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;
}
--
1.7.8
^ permalink raw reply related
* [PATCH v2 18/51] do_for_each_ref_in_array(): new function
From: mhagger @ 2011-12-12 5:38 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Jeff King, Drew Northup, Jakub Narebski, Heiko Voigt,
Johan Herland, Julian Phillips, Michael Haggerty
In-Reply-To: <1323668338-1764-1-git-send-email-mhagger@alum.mit.edu>
From: Michael Haggerty <mhagger@alum.mit.edu>
Extract function do_for_each_ref_in_array() from do_for_each_ref().
The new function will be a useful building block for storing refs
hierarchically.
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
refs.c | 39 +++++++++++++++++++++++----------------
1 files changed, 23 insertions(+), 16 deletions(-)
diff --git a/refs.c b/refs.c
index fb6fe84..bc14437 100644
--- a/refs.c
+++ b/refs.c
@@ -701,21 +701,31 @@ 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)
+{
+ 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;
+}
+
static int do_for_each_ref(const char *submodule, const char *base, each_ref_fn fn,
int trim, int flags, void *cb_data)
{
- int retval = 0, i, p = 0, l = 0;
+ int retval = 0, p = 0, l = 0;
struct ref_cache *refs = get_ref_cache(submodule);
struct ref_array *packed = get_packed_refs(refs);
struct ref_array *loose = get_loose_refs(refs);
- struct ref_array *extra = &extra_refs;
-
- for (i = 0; i < extra->nr; i++) {
- retval = do_one_ref(base, fn, trim, flags, cb_data, extra->refs[i]);
- if (retval)
- goto end_each;
- }
+ retval = do_for_each_ref_in_array(&extra_refs, 0,
+ base, fn, trim, flags, cb_data);
+ if (retval)
+ goto end_each;
while (p < packed->nr && l < loose->nr) {
struct ref_entry *entry;
@@ -735,14 +745,11 @@ static int do_for_each_ref(const char *submodule, const char *base, each_ref_fn
}
if (l < loose->nr) {
- p = l;
- packed = loose;
- }
-
- for (; p < packed->nr; p++) {
- retval = do_one_ref(base, fn, trim, flags, cb_data, packed->refs[p]);
- if (retval)
- goto end_each;
+ retval = do_for_each_ref_in_array(loose, l,
+ base, fn, trim, flags, cb_data);
+ } else {
+ retval = do_for_each_ref_in_array(packed, p,
+ base, fn, trim, flags, cb_data);
}
end_each:
--
1.7.8
^ permalink raw reply related
* [PATCH v2 17/51] do_for_each_ref(): correctly terminate while processesing extra_refs
From: mhagger @ 2011-12-12 5:38 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Jeff King, Drew Northup, Jakub Narebski, Heiko Voigt,
Johan Herland, Julian Phillips, Michael Haggerty
In-Reply-To: <1323668338-1764-1-git-send-email-mhagger@alum.mit.edu>
From: Michael Haggerty <mhagger@alum.mit.edu>
If the user-supplied function returns a nonzero value while processing
extra_refs, terminate without processing the rest of the list.
This probably has no practical importance, but makes the handling of
extra_refs a little bit more consistent with the handling of other
refs.
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
refs.c | 5 ++++-
1 files changed, 4 insertions(+), 1 deletions(-)
diff --git a/refs.c b/refs.c
index 579e4c3..fb6fe84 100644
--- a/refs.c
+++ b/refs.c
@@ -711,8 +711,11 @@ static int do_for_each_ref(const char *submodule, const char *base, each_ref_fn
struct ref_array *extra = &extra_refs;
- for (i = 0; i < extra->nr; i++)
+ for (i = 0; i < extra->nr; i++) {
retval = do_one_ref(base, fn, trim, flags, cb_data, extra->refs[i]);
+ if (retval)
+ goto end_each;
+ }
while (p < packed->nr && l < loose->nr) {
struct ref_entry *entry;
--
1.7.8
^ permalink raw reply related
* [PATCH v2 15/51] create_ref_entry(): extract function from add_ref()
From: mhagger @ 2011-12-12 5:38 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Jeff King, Drew Northup, Jakub Narebski, Heiko Voigt,
Johan Herland, Julian Phillips, Michael Haggerty
In-Reply-To: <1323668338-1764-1-git-send-email-mhagger@alum.mit.edu>
From: Michael Haggerty <mhagger@alum.mit.edu>
Separate the creation of the ref_entry from its addition to a ref_array.
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
refs.c | 37 ++++++++++++++++++++++---------------
1 files changed, 22 insertions(+), 15 deletions(-)
diff --git a/refs.c b/refs.c
index 2e7bc0c..442b87c 100644
--- a/refs.c
+++ b/refs.c
@@ -53,28 +53,35 @@ static const char *parse_ref_line(char *line, unsigned char *sha1)
return line;
}
-/* Add a ref_entry to the end of the ref_array (unsorted). */
-static void add_ref(const char *refname, const unsigned char *sha1,
- int flag, int check_name, struct ref_array *refs,
- struct ref_entry **new_entry)
+static struct ref_entry *create_ref_entry(const char *refname,
+ const unsigned char *sha1, int flag,
+ int check_name)
{
int len;
- struct ref_entry *entry;
+ struct ref_entry *ref;
- /* Allocate it and add it in.. */
- len = strlen(refname) + 1;
- entry = xmalloc(sizeof(struct ref_entry) + len);
- hashcpy(entry->sha1, sha1);
- hashclr(entry->peeled);
if (check_name &&
check_refname_format(refname, REFNAME_ALLOW_ONELEVEL|REFNAME_DOT_COMPONENT))
die("Reference has invalid format: '%s'", refname);
- memcpy(entry->name, refname, len);
- entry->flag = flag;
- if (new_entry)
- *new_entry = entry;
+ len = strlen(refname) + 1;
+ ref = xmalloc(sizeof(struct ref_entry) + len);
+ hashcpy(ref->sha1, sha1);
+ hashclr(ref->peeled);
+ memcpy(ref->name, refname, len);
+ ref->flag = flag;
+ return ref;
+}
+
+/* Add a ref_entry to the end of the ref_array (unsorted). */
+static void add_ref(const char *refname, const unsigned char *sha1,
+ int flag, int check_name, struct ref_array *refs,
+ struct ref_entry **new_ref)
+{
+ struct ref_entry *ref = create_ref_entry(refname, sha1, flag, check_name);
+ if (new_ref)
+ *new_ref = ref;
ALLOC_GROW(refs->refs, refs->nr + 1, refs->alloc);
- refs->refs[refs->nr++] = entry;
+ refs->refs[refs->nr++] = ref;
}
static int ref_entry_cmp(const void *a, const void *b)
--
1.7.8
^ permalink raw reply related
* [PATCH v2 13/51] resolve_gitlink_ref_recursive(): change to work with struct ref_cache
From: mhagger @ 2011-12-12 5:38 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Jeff King, Drew Northup, Jakub Narebski, Heiko Voigt,
Johan Herland, Julian Phillips, Michael Haggerty
In-Reply-To: <1323668338-1764-1-git-send-email-mhagger@alum.mit.edu>
From: Michael Haggerty <mhagger@alum.mit.edu>
resolve_gitlink_ref() and resolve_gitlink_ref_recursive(), together,
basically duplicated the code in git_path_submodule(). So use that
function instead.
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
refs.c | 34 ++++++++++------------------------
1 files changed, 10 insertions(+), 24 deletions(-)
diff --git a/refs.c b/refs.c
index bf1f164..ba7a8b0 100644
--- a/refs.c
+++ b/refs.c
@@ -431,17 +431,19 @@ static int resolve_gitlink_packed_ref(struct ref_cache *refs,
}
static int resolve_gitlink_ref_recursive(struct ref_cache *refs,
- char *name, int pathlen,
const char *refname, unsigned char *sha1,
int recursion)
{
- int fd, len = strlen(refname);
+ int fd, len;
char buffer[128], *p;
+ char *path;
- if (recursion > MAXDEPTH || len > MAXREFLEN)
+ if (recursion > MAXDEPTH || strlen(refname) > MAXREFLEN)
return -1;
- memcpy(name + pathlen, refname, len+1);
- fd = open(name, O_RDONLY);
+ path = *refs->name
+ ? git_path_submodule(refs->name, "%s", refname)
+ : git_path("%s", refname);
+ fd = open(path, O_RDONLY);
if (fd < 0)
return resolve_gitlink_packed_ref(refs, refname, sha1);
@@ -464,15 +466,14 @@ static int resolve_gitlink_ref_recursive(struct ref_cache *refs,
while (isspace(*p))
p++;
- return resolve_gitlink_ref_recursive(refs, name, pathlen, p, sha1, recursion+1);
+ return resolve_gitlink_ref_recursive(refs, p, sha1, recursion+1);
}
int resolve_gitlink_ref(const char *path, const char *refname, unsigned char *sha1)
{
int len = strlen(path), retval;
- char *submodule, *gitdir;
+ char *submodule;
struct ref_cache *refs;
- const char *tmp;
while (len && path[len-1] == '/')
len--;
@@ -482,22 +483,7 @@ int resolve_gitlink_ref(const char *path, const char *refname, unsigned char *sh
refs = get_ref_cache(submodule);
free(submodule);
- gitdir = xmalloc(len + MAXREFLEN + 8);
- memcpy(gitdir, path, len);
- memcpy(gitdir + len, "/.git", 6);
- len += 5;
-
- tmp = read_gitfile(gitdir);
- if (tmp) {
- free(gitdir);
- len = strlen(tmp);
- gitdir = xmalloc(len + MAXREFLEN + 3);
- memcpy(gitdir, tmp, len);
- }
- gitdir[len] = '/';
- gitdir[++len] = '\0';
- retval = resolve_gitlink_ref_recursive(refs, gitdir, len, refname, sha1, 0);
- free(gitdir);
+ retval = resolve_gitlink_ref_recursive(refs, refname, sha1, 0);
return retval;
}
--
1.7.8
^ permalink raw reply related
* [PATCH v2 12/51] Pass a (ref_cache *) to the resolve_gitlink_*() helper functions
From: mhagger @ 2011-12-12 5:38 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Jeff King, Drew Northup, Jakub Narebski, Heiko Voigt,
Johan Herland, Julian Phillips, Michael Haggerty
In-Reply-To: <1323668338-1764-1-git-send-email-mhagger@alum.mit.edu>
From: Michael Haggerty <mhagger@alum.mit.edu>
And remove some redundant arguments from resolve_gitlink_packed_ref().
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
refs.c | 40 ++++++++++++++++++++--------------------
1 files changed, 20 insertions(+), 20 deletions(-)
diff --git a/refs.c b/refs.c
index 91ec395..bf1f164 100644
--- a/refs.c
+++ b/refs.c
@@ -413,30 +413,25 @@ static struct ref_array *get_loose_refs(struct ref_cache *refs)
/*
* Called by resolve_gitlink_ref_recursive() after it failed to read
- * from "name", which is "module/.git/<refname>". Find <refname> in
- * the packed-refs file for the submodule.
+ * from the loose refs in ref_cache refs. Find <refname> in the
+ * packed-refs file for the submodule.
*/
-static int resolve_gitlink_packed_ref(char *name, int pathlen,
+static int resolve_gitlink_packed_ref(struct ref_cache *refs,
const char *refname, unsigned char *sha1)
{
- int retval = -1;
struct ref_entry *ref;
- struct ref_array *array;
+ struct ref_array *array = get_packed_refs(refs);
- /* being defensive: resolve_gitlink_ref() did this for us */
- if (pathlen < 6 || memcmp(name + pathlen - 6, "/.git/", 6))
- die("Oops");
- name[pathlen - 6] = '\0'; /* make it path to the submodule */
- array = get_packed_refs(get_ref_cache(name));
ref = search_ref_array(array, refname);
- if (ref != NULL) {
- memcpy(sha1, ref->sha1, 20);
- retval = 0;
- }
- return retval;
+ if (ref == NULL)
+ return -1;
+
+ memcpy(sha1, ref->sha1, 20);
+ return 0;
}
-static int resolve_gitlink_ref_recursive(char *name, int pathlen,
+static int resolve_gitlink_ref_recursive(struct ref_cache *refs,
+ char *name, int pathlen,
const char *refname, unsigned char *sha1,
int recursion)
{
@@ -448,7 +443,7 @@ static int resolve_gitlink_ref_recursive(char *name, int pathlen,
memcpy(name + pathlen, refname, len+1);
fd = open(name, O_RDONLY);
if (fd < 0)
- return resolve_gitlink_packed_ref(name, pathlen, refname, sha1);
+ return resolve_gitlink_packed_ref(refs, refname, sha1);
len = read(fd, buffer, sizeof(buffer)-1);
close(fd);
@@ -469,19 +464,24 @@ static int resolve_gitlink_ref_recursive(char *name, int pathlen,
while (isspace(*p))
p++;
- return resolve_gitlink_ref_recursive(name, pathlen, p, sha1, recursion+1);
+ return resolve_gitlink_ref_recursive(refs, name, pathlen, p, sha1, recursion+1);
}
int resolve_gitlink_ref(const char *path, const char *refname, unsigned char *sha1)
{
int len = strlen(path), retval;
- char *gitdir;
+ char *submodule, *gitdir;
+ struct ref_cache *refs;
const char *tmp;
while (len && path[len-1] == '/')
len--;
if (!len)
return -1;
+ submodule = xstrndup(path, len);
+ refs = get_ref_cache(submodule);
+ free(submodule);
+
gitdir = xmalloc(len + MAXREFLEN + 8);
memcpy(gitdir, path, len);
memcpy(gitdir + len, "/.git", 6);
@@ -496,7 +496,7 @@ int resolve_gitlink_ref(const char *path, const char *refname, unsigned char *sh
}
gitdir[len] = '/';
gitdir[++len] = '\0';
- retval = resolve_gitlink_ref_recursive(gitdir, len, refname, sha1, 0);
+ retval = resolve_gitlink_ref_recursive(refs, gitdir, len, refname, sha1, 0);
free(gitdir);
return retval;
}
--
1.7.8
^ permalink raw reply related
* [PATCH v2 10/51] get_ref_dir(): change signature
From: mhagger @ 2011-12-12 5:38 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Jeff King, Drew Northup, Jakub Narebski, Heiko Voigt,
Johan Herland, Julian Phillips, Michael Haggerty
In-Reply-To: <1323668338-1764-1-git-send-email-mhagger@alum.mit.edu>
From: Michael Haggerty <mhagger@alum.mit.edu>
Change get_ref_dir() to take a (struct ref_cache *) in place of the
submodule name.
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
refs.c | 18 +++++++++---------
1 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/refs.c b/refs.c
index c62c682..91ec395 100644
--- a/refs.c
+++ b/refs.c
@@ -298,14 +298,14 @@ static struct ref_array *get_packed_refs(struct ref_cache *refs)
return &refs->packed;
}
-static void get_ref_dir(const char *submodule, const char *base,
+static void get_ref_dir(struct ref_cache *refs, const char *base,
struct ref_array *array)
{
DIR *dir;
const char *path;
- if (*submodule)
- path = git_path_submodule(submodule, "%s", base);
+ if (*refs->name)
+ path = git_path_submodule(refs->name, "%s", base);
else
path = git_path("%s", base);
@@ -336,19 +336,19 @@ static void get_ref_dir(const char *submodule, const char *base,
if (has_extension(de->d_name, ".lock"))
continue;
memcpy(refname + baselen, de->d_name, namelen+1);
- refdir = submodule
- ? git_path_submodule(submodule, "%s", refname)
+ refdir = *refs->name
+ ? git_path_submodule(refs->name, "%s", refname)
: git_path("%s", refname);
if (stat(refdir, &st) < 0)
continue;
if (S_ISDIR(st.st_mode)) {
- get_ref_dir(submodule, refname, array);
+ get_ref_dir(refs, refname, array);
continue;
}
- if (submodule) {
+ if (*refs->name) {
hashclr(sha1);
flag = 0;
- if (resolve_gitlink_ref(submodule, refname, sha1) < 0) {
+ if (resolve_gitlink_ref(refs->name, refname, sha1) < 0) {
hashclr(sha1);
flag |= REF_ISBROKEN;
}
@@ -400,7 +400,7 @@ void warn_dangling_symref(FILE *fp, const char *msg_fmt, const char *refname)
static struct ref_array *get_loose_refs(struct ref_cache *refs)
{
if (!refs->did_loose) {
- get_ref_dir(refs->name, "refs", &refs->loose);
+ get_ref_dir(refs, "refs", &refs->loose);
sort_ref_array(&refs->loose);
refs->did_loose = 1;
}
--
1.7.8
^ permalink raw reply related
* [PATCH v2 11/51] resolve_gitlink_ref(): improve docstring
From: mhagger @ 2011-12-12 5:38 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Jeff King, Drew Northup, Jakub Narebski, Heiko Voigt,
Johan Herland, Julian Phillips, Michael Haggerty
In-Reply-To: <1323668338-1764-1-git-send-email-mhagger@alum.mit.edu>
From: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
refs.h | 8 ++++++--
1 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/refs.h b/refs.h
index 4c5d570..d498291 100644
--- a/refs.h
+++ b/refs.h
@@ -133,8 +133,12 @@ extern char *shorten_unambiguous_ref(const char *refname, int strict);
/** rename ref, return 0 on success **/
extern int rename_ref(const char *oldref, const char *newref, const char *logmsg);
-/** resolve ref in nested "gitlink" repository */
-extern int resolve_gitlink_ref(const char *name, const char *refname, unsigned char *sha1);
+/**
+ * Resolve refname in the nested "gitlink" repository that is located
+ * at path. If the resolution is successful, return 0 and set sha1 to
+ * the name of the object; otherwise, return a non-zero value.
+ */
+extern int resolve_gitlink_ref(const char *path, const char *refname, unsigned char *sha1);
/** lock a ref and then write its file */
enum action_on_err { MSG_ON_ERR, DIE_ON_ERR, QUIET_ON_ERR };
--
1.7.8
^ permalink raw reply related
* [PATCH v2 09/51] refs: change signatures of get_packed_refs() and get_loose_refs()
From: mhagger @ 2011-12-12 5:38 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Jeff King, Drew Northup, Jakub Narebski, Heiko Voigt,
Johan Herland, Julian Phillips, Michael Haggerty
In-Reply-To: <1323668338-1764-1-git-send-email-mhagger@alum.mit.edu>
From: Michael Haggerty <mhagger@alum.mit.edu>
Change get_packed_refs() and get_loose_refs() to take a (struct
ref_cache *) instead of the name of the submodule.
Change get_ref_dir() to take a submodule name (i.e., "" for the main
module) rather than a submodule pointer (i.e., NULL for the main
module) so that refs->name can be used as its argument. (In a moment
this function will also be changed to take a (struct ref_cache *),
too.)
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
refs.c | 36 +++++++++++++++++-------------------
1 files changed, 17 insertions(+), 19 deletions(-)
diff --git a/refs.c b/refs.c
index ea058c1..c62c682 100644
--- a/refs.c
+++ b/refs.c
@@ -278,16 +278,14 @@ void clear_extra_refs(void)
clear_ref_array(&extra_refs);
}
-static struct ref_array *get_packed_refs(const char *submodule)
+static struct ref_array *get_packed_refs(struct ref_cache *refs)
{
- struct ref_cache *refs = get_ref_cache(submodule);
-
if (!refs->did_packed) {
const char *packed_refs_file;
FILE *f;
- if (submodule)
- packed_refs_file = git_path_submodule(submodule, "packed-refs");
+ if (*refs->name)
+ packed_refs_file = git_path_submodule(refs->name, "packed-refs");
else
packed_refs_file = git_path("packed-refs");
f = fopen(packed_refs_file, "r");
@@ -306,7 +304,7 @@ static void get_ref_dir(const char *submodule, const char *base,
DIR *dir;
const char *path;
- if (submodule)
+ if (*submodule)
path = git_path_submodule(submodule, "%s", base);
else
path = git_path("%s", base);
@@ -399,12 +397,10 @@ void warn_dangling_symref(FILE *fp, const char *msg_fmt, const char *refname)
for_each_rawref(warn_if_dangling_symref, &data);
}
-static struct ref_array *get_loose_refs(const char *submodule)
+static struct ref_array *get_loose_refs(struct ref_cache *refs)
{
- struct ref_cache *refs = get_ref_cache(submodule);
-
if (!refs->did_loose) {
- get_ref_dir(submodule, "refs", &refs->loose);
+ get_ref_dir(refs->name, "refs", &refs->loose);
sort_ref_array(&refs->loose);
refs->did_loose = 1;
}
@@ -431,7 +427,7 @@ static int resolve_gitlink_packed_ref(char *name, int pathlen,
if (pathlen < 6 || memcmp(name + pathlen - 6, "/.git/", 6))
die("Oops");
name[pathlen - 6] = '\0'; /* make it path to the submodule */
- array = get_packed_refs(name);
+ array = get_packed_refs(get_ref_cache(name));
ref = search_ref_array(array, refname);
if (ref != NULL) {
memcpy(sha1, ref->sha1, 20);
@@ -511,7 +507,7 @@ int resolve_gitlink_ref(const char *path, const char *refname, unsigned char *sh
*/
static int get_packed_ref(const char *refname, unsigned char *sha1)
{
- struct ref_array *packed = get_packed_refs(NULL);
+ struct ref_array *packed = get_packed_refs(get_ref_cache(NULL));
struct ref_entry *entry = search_ref_array(packed, refname);
if (entry) {
hashcpy(sha1, entry->sha1);
@@ -695,7 +691,7 @@ int peel_ref(const char *refname, unsigned char *sha1)
return -1;
if ((flag & REF_ISPACKED)) {
- struct ref_array *array = get_packed_refs(NULL);
+ struct ref_array *array = get_packed_refs(get_ref_cache(NULL));
struct ref_entry *r = search_ref_array(array, refname);
if (r != NULL && r->flag & REF_KNOWS_PEELED) {
@@ -720,8 +716,9 @@ static int do_for_each_ref(const char *submodule, const char *base, each_ref_fn
int trim, int flags, void *cb_data)
{
int retval = 0, i, p = 0, l = 0;
- struct ref_array *packed = get_packed_refs(submodule);
- struct ref_array *loose = get_loose_refs(submodule);
+ struct ref_cache *refs = get_ref_cache(submodule);
+ struct ref_array *packed = get_packed_refs(refs);
+ struct ref_array *loose = get_loose_refs(refs);
struct ref_array *extra = &extra_refs;
@@ -1238,7 +1235,7 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname,
* name is a proper prefix of our refname.
*/
if (missing &&
- !is_refname_available(refname, NULL, get_packed_refs(NULL))) {
+ !is_refname_available(refname, NULL, get_packed_refs(get_ref_cache(NULL)))) {
last_errno = ENOTDIR;
goto error_return;
}
@@ -1298,7 +1295,7 @@ static int repack_without_ref(const char *refname)
struct ref_entry *ref;
int fd, i;
- packed = get_packed_refs(NULL);
+ packed = get_packed_refs(get_ref_cache(NULL));
ref = search_ref_array(packed, refname);
if (ref == NULL)
return 0;
@@ -1381,6 +1378,7 @@ int rename_ref(const char *oldrefname, const char *newrefname, const char *logms
struct stat loginfo;
int log = !lstat(git_path("logs/%s", oldrefname), &loginfo);
const char *symref = NULL;
+ struct ref_cache *refs = get_ref_cache(NULL);
if (log && S_ISLNK(loginfo.st_mode))
return error("reflog for %s is a symlink", oldrefname);
@@ -1392,10 +1390,10 @@ int rename_ref(const char *oldrefname, const char *newrefname, const char *logms
if (!symref)
return error("refname %s not found", oldrefname);
- if (!is_refname_available(newrefname, oldrefname, get_packed_refs(NULL)))
+ if (!is_refname_available(newrefname, oldrefname, get_packed_refs(refs)))
return 1;
- if (!is_refname_available(newrefname, oldrefname, get_loose_refs(NULL)))
+ if (!is_refname_available(newrefname, oldrefname, get_loose_refs(refs)))
return 1;
if (log && rename(git_path("logs/%s", oldrefname), git_path(TMP_RENAMED_LOG)))
--
1.7.8
^ permalink raw reply related
* [PATCH v2 08/51] is_dup_ref(): extract function from sort_ref_array()
From: mhagger @ 2011-12-12 5:38 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Jeff King, Drew Northup, Jakub Narebski, Heiko Voigt,
Johan Herland, Julian Phillips, Michael Haggerty
In-Reply-To: <1323668338-1764-1-git-send-email-mhagger@alum.mit.edu>
From: Michael Haggerty <mhagger@alum.mit.edu>
Giving the function a name makes the code easier to understand.
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
refs.c | 37 +++++++++++++++++++++++++------------
1 files changed, 25 insertions(+), 12 deletions(-)
diff --git a/refs.c b/refs.c
index 2252c66..ea058c1 100644
--- a/refs.c
+++ b/refs.c
@@ -84,9 +84,28 @@ static int ref_entry_cmp(const void *a, const void *b)
return strcmp(one->name, two->name);
}
+/*
+ * 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
+ * sha1s.
+ */
+static int is_dup_ref(const struct ref_entry *ref1, const struct ref_entry *ref2)
+{
+ if (!strcmp(ref1->name, ref2->name)) {
+ /* Duplicate name; make sure that the SHA1s match: */
+ if (hashcmp(ref1->sha1, ref2->sha1))
+ die("Duplicated ref, and SHA1s don't match: %s",
+ ref1->name);
+ warning("Duplicated ref: %s", ref1->name);
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
static void sort_ref_array(struct ref_array *array)
{
- int i = 0, j = 1;
+ int i, j;
/* Nothing to sort unless there are at least two entries */
if (array->nr < 2)
@@ -95,19 +114,13 @@ static void sort_ref_array(struct ref_array *array)
qsort(array->refs, array->nr, sizeof(*array->refs), ref_entry_cmp);
/* Remove any duplicates from the ref_array */
- for (; j < array->nr; j++) {
- struct ref_entry *a = array->refs[i];
- struct ref_entry *b = array->refs[j];
- if (!strcmp(a->name, b->name)) {
- if (hashcmp(a->sha1, b->sha1))
- die("Duplicated ref, and SHA1s don't match: %s",
- a->name);
- warning("Duplicated ref: %s", a->name);
- free(b);
+ i = 0;
+ for (j = 1; j < array->nr; j++) {
+ if (is_dup_ref(array->refs[i], array->refs[j])) {
+ free(array->refs[j]);
continue;
}
- i++;
- array->refs[i] = array->refs[j];
+ array->refs[++i] = array->refs[j];
}
array->nr = i + 1;
}
--
1.7.8
^ permalink raw reply related
* [PATCH v2 07/51] add_ref(): add docstring
From: mhagger @ 2011-12-12 5:38 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Jeff King, Drew Northup, Jakub Narebski, Heiko Voigt,
Johan Herland, Julian Phillips, Michael Haggerty
In-Reply-To: <1323668338-1764-1-git-send-email-mhagger@alum.mit.edu>
From: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
refs.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/refs.c b/refs.c
index 1975792..2252c66 100644
--- a/refs.c
+++ b/refs.c
@@ -53,6 +53,7 @@ static const char *parse_ref_line(char *line, unsigned char *sha1)
return line;
}
+/* Add a ref_entry to the end of the ref_array (unsorted). */
static void add_ref(const char *refname, const unsigned char *sha1,
int flag, int check_name, struct ref_array *refs,
struct ref_entry **new_entry)
--
1.7.8
^ permalink raw reply related
* [PATCH v2 05/51] is_refname_available(): remove the "quiet" argument
From: mhagger @ 2011-12-12 5:38 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Jeff King, Drew Northup, Jakub Narebski, Heiko Voigt,
Johan Herland, Julian Phillips, Michael Haggerty
In-Reply-To: <1323668338-1764-1-git-send-email-mhagger@alum.mit.edu>
From: Michael Haggerty <mhagger@alum.mit.edu>
quiet was always set to 0, so get rid of it. Add a function docstring
for good measure.
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
refs.c | 20 +++++++++++++-------
1 files changed, 13 insertions(+), 7 deletions(-)
diff --git a/refs.c b/refs.c
index 7be91d1..d7d422f 100644
--- a/refs.c
+++ b/refs.c
@@ -1057,8 +1057,15 @@ static int remove_empty_directories(const char *file)
return result;
}
+/*
+ * 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, int quiet)
+ struct ref_array *array)
{
int i, namlen = strlen(refname); /* e.g. 'foo/bar' */
for (i = 0; i < array->nr; i++ ) {
@@ -1070,9 +1077,8 @@ static int is_refname_available(const char *refname, const char *oldrefname,
const char *lead = (namlen < len) ? entry->name : refname;
if (!strncmp(refname, entry->name, cmplen) &&
lead[cmplen] == '/') {
- if (!quiet)
- error("'%s' exists; cannot create '%s'",
- entry->name, refname);
+ error("'%s' exists; cannot create '%s'",
+ entry->name, refname);
return 0;
}
}
@@ -1213,7 +1219,7 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname,
* name is a proper prefix of our refname.
*/
if (missing &&
- !is_refname_available(refname, NULL, get_packed_refs(NULL), 0)) {
+ !is_refname_available(refname, NULL, get_packed_refs(NULL))) {
last_errno = ENOTDIR;
goto error_return;
}
@@ -1367,10 +1373,10 @@ int rename_ref(const char *oldrefname, const char *newrefname, const char *logms
if (!symref)
return error("refname %s not found", oldrefname);
- if (!is_refname_available(newrefname, oldrefname, get_packed_refs(NULL), 0))
+ if (!is_refname_available(newrefname, oldrefname, get_packed_refs(NULL)))
return 1;
- if (!is_refname_available(newrefname, oldrefname, get_loose_refs(NULL), 0))
+ if (!is_refname_available(newrefname, oldrefname, get_loose_refs(NULL)))
return 1;
if (log && rename(git_path("logs/%s", oldrefname), git_path(TMP_RENAMED_LOG)))
--
1.7.8
^ permalink raw reply related
* [PATCH v2 06/51] parse_ref_line(): add docstring
From: mhagger @ 2011-12-12 5:38 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Jeff King, Drew Northup, Jakub Narebski, Heiko Voigt,
Johan Herland, Julian Phillips, Michael Haggerty
In-Reply-To: <1323668338-1764-1-git-send-email-mhagger@alum.mit.edu>
From: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
refs.c | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/refs.c b/refs.c
index d7d422f..1975792 100644
--- a/refs.c
+++ b/refs.c
@@ -20,6 +20,11 @@ struct ref_array {
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)
{
/*
--
1.7.8
^ permalink raw reply related
* [PATCH v2 02/51] refs: rename "refname" variables
From: mhagger @ 2011-12-12 5:38 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Jeff King, Drew Northup, Jakub Narebski, Heiko Voigt,
Johan Herland, Julian Phillips, Michael Haggerty
In-Reply-To: <1323668338-1764-1-git-send-email-mhagger@alum.mit.edu>
From: Michael Haggerty <mhagger@alum.mit.edu>
Try to consistently use the variable name "refname" when referring to
a string that names a reference.
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
cache.h | 6 +-
refs.c | 306 ++++++++++++++++++++++++++++++++-------------------------------
refs.h | 26 +++---
3 files changed, 175 insertions(+), 163 deletions(-)
diff --git a/cache.h b/cache.h
index 8c98d05..e1644b1 100644
--- a/cache.h
+++ b/cache.h
@@ -831,9 +831,9 @@ static inline int get_sha1_with_context(const char *str, unsigned char *sha1, st
extern int get_sha1_hex(const char *hex, unsigned char *sha1);
extern char *sha1_to_hex(const unsigned char *sha1); /* static buffer result! */
-extern int read_ref_full(const char *filename, unsigned char *sha1,
+extern int read_ref_full(const char *refname, unsigned char *sha1,
int reading, int *flags);
-extern int read_ref(const char *filename, unsigned char *sha1);
+extern int read_ref(const char *refname, unsigned char *sha1);
/*
* Resolve a reference, recursively following symbolic refererences.
@@ -865,7 +865,7 @@ extern int read_ref(const char *filename, unsigned char *sha1);
*
* errno is sometimes set on errors, but not always.
*/
-extern const char *resolve_ref(const char *ref, unsigned char *sha1, int reading, int *flag);
+extern const char *resolve_ref(const char *refname, unsigned char *sha1, int reading, int *flag);
extern int dwim_ref(const char *str, int len, unsigned char *sha1, char **ref);
extern int dwim_log(const char *str, int len, unsigned char *sha1, char **ref);
diff --git a/refs.c b/refs.c
index 669782f..8ddd874 100644
--- a/refs.c
+++ b/refs.c
@@ -48,7 +48,7 @@ static const char *parse_ref_line(char *line, unsigned char *sha1)
return line;
}
-static void add_ref(const char *name, const unsigned char *sha1,
+static void add_ref(const char *refname, const unsigned char *sha1,
int flag, int check_name, struct ref_array *refs,
struct ref_entry **new_entry)
{
@@ -56,14 +56,14 @@ static void add_ref(const char *name, const unsigned char *sha1,
struct ref_entry *entry;
/* Allocate it and add it in.. */
- len = strlen(name) + 1;
+ len = strlen(refname) + 1;
entry = xmalloc(sizeof(struct ref_entry) + len);
hashcpy(entry->sha1, sha1);
hashclr(entry->peeled);
if (check_name &&
- check_refname_format(name, REFNAME_ALLOW_ONELEVEL|REFNAME_DOT_COMPONENT))
- die("Reference has invalid format: '%s'", name);
- memcpy(entry->name, name, len);
+ check_refname_format(refname, REFNAME_ALLOW_ONELEVEL|REFNAME_DOT_COMPONENT))
+ die("Reference has invalid format: '%s'", refname);
+ memcpy(entry->name, refname, len);
entry->flag = flag;
if (new_entry)
*new_entry = entry;
@@ -106,20 +106,20 @@ 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 *name)
+static struct ref_entry *search_ref_array(struct ref_array *array, const char *refname)
{
struct ref_entry *e, **r;
int len;
- if (name == NULL)
+ if (refname == NULL)
return NULL;
if (!array->nr)
return NULL;
- len = strlen(name) + 1;
+ len = strlen(refname) + 1;
e = xmalloc(sizeof(struct ref_entry) + len);
- memcpy(e->name, name, len);
+ memcpy(e->name, refname, len);
r = bsearch(&e, array->refs, array->nr, sizeof(*array->refs), ref_entry_cmp);
@@ -223,7 +223,7 @@ static void read_packed_refs(FILE *f, struct ref_array *array)
while (fgets(refline, sizeof(refline), f)) {
unsigned char sha1[20];
- const char *name;
+ const char *refname;
static const char header[] = "# pack-refs with:";
if (!strncmp(refline, header, sizeof(header)-1)) {
@@ -234,9 +234,9 @@ static void read_packed_refs(FILE *f, struct ref_array *array)
continue;
}
- name = parse_ref_line(refline, sha1);
- if (name) {
- add_ref(name, sha1, flag, 1, array, &last);
+ refname = parse_ref_line(refline, sha1);
+ if (refname) {
+ add_ref(refname, sha1, flag, 1, array, &last);
continue;
}
if (last &&
@@ -249,9 +249,9 @@ static void read_packed_refs(FILE *f, struct ref_array *array)
sort_ref_array(array);
}
-void add_extra_ref(const char *name, const unsigned char *sha1, int flag)
+void add_extra_ref(const char *refname, const unsigned char *sha1, int flag)
{
- add_ref(name, sha1, flag, 0, &extra_refs, NULL);
+ add_ref(refname, sha1, flag, 0, &extra_refs, NULL);
}
void clear_extra_refs(void)
@@ -298,11 +298,11 @@ static void get_ref_dir(const char *submodule, const char *base,
if (dir) {
struct dirent *de;
int baselen = strlen(base);
- char *ref = xmalloc(baselen + 257);
+ char *refname = xmalloc(baselen + 257);
- memcpy(ref, base, baselen);
+ memcpy(refname, base, baselen);
if (baselen && base[baselen-1] != '/')
- ref[baselen++] = '/';
+ refname[baselen++] = '/';
while ((de = readdir(dir)) != NULL) {
unsigned char sha1[20];
@@ -318,30 +318,30 @@ static void get_ref_dir(const char *submodule, const char *base,
continue;
if (has_extension(de->d_name, ".lock"))
continue;
- memcpy(ref + baselen, de->d_name, namelen+1);
+ memcpy(refname + baselen, de->d_name, namelen+1);
refdir = submodule
- ? git_path_submodule(submodule, "%s", ref)
- : git_path("%s", ref);
+ ? git_path_submodule(submodule, "%s", refname)
+ : git_path("%s", refname);
if (stat(refdir, &st) < 0)
continue;
if (S_ISDIR(st.st_mode)) {
- get_ref_dir(submodule, ref, array);
+ get_ref_dir(submodule, refname, array);
continue;
}
if (submodule) {
hashclr(sha1);
flag = 0;
- if (resolve_gitlink_ref(submodule, ref, sha1) < 0) {
+ if (resolve_gitlink_ref(submodule, refname, sha1) < 0) {
hashclr(sha1);
flag |= REF_ISBROKEN;
}
- } else if (read_ref_full(ref, sha1, 1, &flag)) {
+ } else if (read_ref_full(refname, sha1, 1, &flag)) {
hashclr(sha1);
flag |= REF_ISBROKEN;
}
- add_ref(ref, sha1, flag, 1, array, NULL);
+ add_ref(refname, sha1, flag, 1, array, NULL);
}
- free(ref);
+ free(refname);
closedir(dir);
}
}
@@ -401,7 +401,8 @@ static struct ref_array *get_loose_refs(const char *submodule)
* from "name", which is "module/.git/<refname>". Find <refname> in
* the packed-refs file for the submodule.
*/
-static int resolve_gitlink_packed_ref(char *name, int pathlen, const char *refname, unsigned char *result)
+static int resolve_gitlink_packed_ref(char *name, int pathlen,
+ const char *refname, unsigned char *result)
{
int retval = -1;
struct ref_entry *ref;
@@ -420,7 +421,9 @@ static int resolve_gitlink_packed_ref(char *name, int pathlen, const char *refna
return retval;
}
-static int resolve_gitlink_ref_recursive(char *name, int pathlen, const char *refname, unsigned char *result, int recursion)
+static int resolve_gitlink_ref_recursive(char *name, int pathlen,
+ const char *refname, unsigned char *result,
+ int recursion)
{
int fd, len = strlen(refname);
char buffer[128], *p;
@@ -487,10 +490,10 @@ int resolve_gitlink_ref(const char *path, const char *refname, unsigned char *re
* Try to read ref from the packed references. On success, set sha1
* and return 0; otherwise, return -1.
*/
-static int get_packed_ref(const char *ref, unsigned char *sha1)
+static int get_packed_ref(const char *refname, unsigned char *sha1)
{
struct ref_array *packed = get_packed_refs(NULL);
- struct ref_entry *entry = search_ref_array(packed, ref);
+ struct ref_entry *entry = search_ref_array(packed, refname);
if (entry) {
hashcpy(sha1, entry->sha1);
return 0;
@@ -498,17 +501,17 @@ static int get_packed_ref(const char *ref, unsigned char *sha1)
return -1;
}
-const char *resolve_ref(const char *ref, unsigned char *sha1, int reading, int *flag)
+const char *resolve_ref(const char *refname, unsigned char *sha1, int reading, int *flag)
{
int depth = MAXDEPTH;
ssize_t len;
char buffer[256];
- static char ref_buffer[256];
+ static char refname_buffer[256];
if (flag)
*flag = 0;
- if (check_refname_format(ref, REFNAME_ALLOW_ONELEVEL))
+ if (check_refname_format(refname, REFNAME_ALLOW_ONELEVEL))
return NULL;
for (;;) {
@@ -520,7 +523,7 @@ const char *resolve_ref(const char *ref, unsigned char *sha1, int reading, int *
if (--depth < 0)
return NULL;
- git_snpath(path, sizeof(path), "%s", ref);
+ git_snpath(path, sizeof(path), "%s", refname);
if (lstat(path, &st) < 0) {
if (errno != ENOENT)
@@ -529,17 +532,17 @@ const char *resolve_ref(const char *ref, unsigned char *sha1, int reading, int *
* The loose reference file does not exist;
* check for a packed reference.
*/
- if (!get_packed_ref(ref, sha1)) {
+ if (!get_packed_ref(refname, sha1)) {
if (flag)
*flag |= REF_ISPACKED;
- return ref;
+ return refname;
}
/* The reference is not a packed reference, either. */
if (reading) {
return NULL;
} else {
hashclr(sha1);
- return ref;
+ return refname;
}
}
@@ -551,8 +554,8 @@ const char *resolve_ref(const char *ref, unsigned char *sha1, int reading, int *
buffer[len] = 0;
if (!prefixcmp(buffer, "refs/") &&
!check_refname_format(buffer, 0)) {
- strcpy(ref_buffer, buffer);
- ref = ref_buffer;
+ strcpy(refname_buffer, buffer);
+ refname = refname_buffer;
if (flag)
*flag |= REF_ISSYMREF;
continue;
@@ -595,7 +598,7 @@ const char *resolve_ref(const char *ref, unsigned char *sha1, int reading, int *
*flag |= REF_ISBROKEN;
return NULL;
}
- ref = strcpy(ref_buffer, buf);
+ refname = strcpy(refname_buffer, buf);
}
/* Please note that FETCH_HEAD has a second line containing other data. */
if (get_sha1_hex(buffer, sha1) || (buffer[40] != '\0' && !isspace(buffer[40]))) {
@@ -603,7 +606,7 @@ const char *resolve_ref(const char *ref, unsigned char *sha1, int reading, int *
*flag |= REF_ISBROKEN;
return NULL;
}
- return ref;
+ return refname;
}
/* The argument to filter_refs */
@@ -613,16 +616,16 @@ struct ref_filter {
void *cb_data;
};
-int read_ref_full(const char *ref, unsigned char *sha1, int reading, int *flags)
+int read_ref_full(const char *refname, unsigned char *sha1, int reading, int *flags)
{
- if (resolve_ref(ref, sha1, reading, flags))
+ if (resolve_ref(refname, sha1, reading, flags))
return 0;
return -1;
}
-int read_ref(const char *ref, unsigned char *sha1)
+int read_ref(const char *refname, unsigned char *sha1)
{
- return read_ref_full(ref, sha1, 1, NULL);
+ return read_ref_full(refname, sha1, 1, NULL);
}
#define DO_FOR_EACH_INCLUDE_BROKEN 01
@@ -644,23 +647,23 @@ static int do_one_ref(const char *base, each_ref_fn fn, int trim,
return fn(entry->name + trim, entry->sha1, entry->flag, cb_data);
}
-static int filter_refs(const char *ref, const unsigned char *sha, int flags,
- void *data)
+static int filter_refs(const char *refname, const unsigned char *sha, int flags,
+ void *data)
{
struct ref_filter *filter = (struct ref_filter *)data;
- if (fnmatch(filter->pattern, ref, 0))
+ if (fnmatch(filter->pattern, refname, 0))
return 0;
- return filter->fn(ref, sha, flags, filter->cb_data);
+ return filter->fn(refname, sha, flags, filter->cb_data);
}
-int peel_ref(const char *ref, unsigned char *sha1)
+int peel_ref(const char *refname, unsigned char *sha1)
{
int flag;
unsigned char base[20];
struct object *o;
- if (current_ref && (current_ref->name == ref
- || !strcmp(current_ref->name, ref))) {
+ if (current_ref && (current_ref->name == refname
+ || !strcmp(current_ref->name, refname))) {
if (current_ref->flag & REF_KNOWS_PEELED) {
hashcpy(sha1, current_ref->peeled);
return 0;
@@ -669,12 +672,12 @@ int peel_ref(const char *ref, unsigned char *sha1)
goto fallback;
}
- if (read_ref_full(ref, base, 1, &flag))
+ if (read_ref_full(refname, base, 1, &flag))
return -1;
if ((flag & REF_ISPACKED)) {
struct ref_array *array = get_packed_refs(NULL);
- struct ref_entry *r = search_ref_array(array, ref);
+ struct ref_entry *r = search_ref_array(array, refname);
if (r != NULL && r->flag & REF_KNOWS_PEELED) {
hashcpy(sha1, r->peeled);
@@ -685,7 +688,7 @@ int peel_ref(const char *ref, unsigned char *sha1)
fallback:
o = parse_object(base);
if (o && o->type == OBJ_TAG) {
- o = deref_tag(o, ref, 0);
+ o = deref_tag(o, refname, 0);
if (o) {
hashcpy(sha1, o->sha1);
return 0;
@@ -915,16 +918,16 @@ static inline int bad_ref_char(int ch)
}
/*
- * Try to read one refname component from the front of ref. Return
+ * 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 *ref, int flags)
+static int check_refname_component(const char *refname, int flags)
{
const char *cp;
char last = '\0';
- for (cp = ref; ; cp++) {
+ for (cp = refname; ; cp++) {
char ch = *cp;
if (ch == '\0' || ch == '/')
break;
@@ -936,34 +939,34 @@ static int check_refname_component(const char *ref, int flags)
return -1; /* Refname contains "@{". */
last = ch;
}
- if (cp == ref)
+ if (cp == refname)
return -1; /* Component has zero length. */
- if (ref[0] == '.') {
+ 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 (ref[1] == '\0')
+ if (refname[1] == '\0')
return -1; /* Component equals ".". */
}
- if (cp - ref >= 5 && !memcmp(cp - 5, ".lock", 5))
+ if (cp - refname >= 5 && !memcmp(cp - 5, ".lock", 5))
return -1; /* Refname ends with ".lock". */
- return cp - ref;
+ return cp - refname;
}
-int check_refname_format(const char *ref, int flags)
+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(ref, flags);
+ component_len = check_refname_component(refname, flags);
if (component_len < 0) {
if ((flags & REFNAME_REFSPEC_PATTERN) &&
- ref[0] == '*' &&
- (ref[1] == '\0' || ref[1] == '/')) {
+ refname[0] == '*' &&
+ (refname[1] == '\0' || refname[1] == '/')) {
/* Accept one wildcard as a full refname component. */
flags &= ~REFNAME_REFSPEC_PATTERN;
component_len = 1;
@@ -972,13 +975,13 @@ int check_refname_format(const char *ref, int flags)
}
}
component_count++;
- if (ref[component_len] == '\0')
+ if (refname[component_len] == '\0')
break;
/* Skip to next component. */
- ref += component_len + 1;
+ refname += component_len + 1;
}
- if (ref[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. */
@@ -1054,22 +1057,22 @@ static int remove_empty_directories(const char *file)
return result;
}
-static int is_refname_available(const char *ref, const char *oldref,
+static int is_refname_available(const char *refname, const char *oldrefname,
struct ref_array *array, int quiet)
{
- int i, namlen = strlen(ref); /* e.g. 'foo/bar' */
+ int i, namlen = strlen(refname); /* e.g. 'foo/bar' */
for (i = 0; i < array->nr; i++ ) {
struct ref_entry *entry = array->refs[i];
/* entry->name could be 'foo' or 'foo/bar/baz' */
- if (!oldref || strcmp(oldref, entry->name)) {
+ if (!oldrefname || strcmp(oldrefname, entry->name)) {
int len = strlen(entry->name);
int cmplen = (namlen < len) ? namlen : len;
- const char *lead = (namlen < len) ? entry->name : ref;
- if (!strncmp(ref, entry->name, cmplen) &&
+ const char *lead = (namlen < len) ? entry->name : refname;
+ if (!strncmp(refname, entry->name, cmplen) &&
lead[cmplen] == '/') {
if (!quiet)
error("'%s' exists; cannot create '%s'",
- entry->name, ref);
+ entry->name, refname);
return 0;
}
}
@@ -1165,10 +1168,12 @@ int dwim_log(const char *str, int len, unsigned char *sha1, char **log)
return logs_found;
}
-static struct ref_lock *lock_ref_sha1_basic(const char *ref, const unsigned char *old_sha1, int flags, int *type_p)
+static struct ref_lock *lock_ref_sha1_basic(const char *refname,
+ const unsigned char *old_sha1,
+ int flags, int *type_p)
{
char *ref_file;
- const char *orig_ref = ref;
+ const char *orig_refname = refname;
struct ref_lock *lock;
int last_errno = 0;
int type, lflags;
@@ -1178,27 +1183,27 @@ static struct ref_lock *lock_ref_sha1_basic(const char *ref, const unsigned char
lock = xcalloc(1, sizeof(struct ref_lock));
lock->lock_fd = -1;
- ref = resolve_ref(ref, lock->old_sha1, mustexist, &type);
- if (!ref && errno == EISDIR) {
+ refname = resolve_ref(refname, lock->old_sha1, mustexist, &type);
+ if (!refname && errno == EISDIR) {
/* we are trying to lock foo but we used to
* have foo/bar which now does not exist;
* it is normal for the empty directory 'foo'
* to remain.
*/
- ref_file = git_path("%s", orig_ref);
+ ref_file = git_path("%s", orig_refname);
if (remove_empty_directories(ref_file)) {
last_errno = errno;
- error("there are still refs under '%s'", orig_ref);
+ error("there are still refs under '%s'", orig_refname);
goto error_return;
}
- ref = resolve_ref(orig_ref, lock->old_sha1, mustexist, &type);
+ refname = resolve_ref(orig_refname, lock->old_sha1, mustexist, &type);
}
if (type_p)
*type_p = type;
- if (!ref) {
+ if (!refname) {
last_errno = errno;
error("unable to resolve reference %s: %s",
- orig_ref, strerror(errno));
+ orig_refname, strerror(errno));
goto error_return;
}
missing = is_null_sha1(lock->old_sha1);
@@ -1208,7 +1213,7 @@ static struct ref_lock *lock_ref_sha1_basic(const char *ref, const unsigned char
* name is a proper prefix of our refname.
*/
if (missing &&
- !is_refname_available(ref, NULL, get_packed_refs(NULL), 0)) {
+ !is_refname_available(refname, NULL, get_packed_refs(NULL), 0)) {
last_errno = ENOTDIR;
goto error_return;
}
@@ -1217,12 +1222,12 @@ static struct ref_lock *lock_ref_sha1_basic(const char *ref, const unsigned char
lflags = LOCK_DIE_ON_ERROR;
if (flags & REF_NODEREF) {
- ref = orig_ref;
+ refname = orig_refname;
lflags |= LOCK_NODEREF;
}
- lock->ref_name = xstrdup(ref);
- lock->orig_ref_name = xstrdup(orig_ref);
- ref_file = git_path("%s", ref);
+ lock->ref_name = xstrdup(refname);
+ lock->orig_ref_name = xstrdup(orig_refname);
+ ref_file = git_path("%s", refname);
if (missing)
lock->force_write = 1;
if ((flags & REF_NODEREF) && (type & REF_ISSYMREF))
@@ -1243,20 +1248,21 @@ static struct ref_lock *lock_ref_sha1_basic(const char *ref, const unsigned char
return NULL;
}
-struct ref_lock *lock_ref_sha1(const char *ref, const unsigned char *old_sha1)
+struct ref_lock *lock_ref_sha1(const char *refname, const unsigned char *old_sha1)
{
char refpath[PATH_MAX];
- if (check_refname_format(ref, 0))
+ if (check_refname_format(refname, 0))
return NULL;
- strcpy(refpath, mkpath("refs/%s", ref));
+ strcpy(refpath, mkpath("refs/%s", refname));
return lock_ref_sha1_basic(refpath, old_sha1, 0, NULL);
}
-struct ref_lock *lock_any_ref_for_update(const char *ref, const unsigned char *old_sha1, int flags)
+struct ref_lock *lock_any_ref_for_update(const char *refname,
+ const unsigned char *old_sha1, int flags)
{
- if (check_refname_format(ref, REFNAME_ALLOW_ONELEVEL))
+ if (check_refname_format(refname, REFNAME_ALLOW_ONELEVEL))
return NULL;
- return lock_ref_sha1_basic(ref, old_sha1, flags, NULL);
+ return lock_ref_sha1_basic(refname, old_sha1, flags, NULL);
}
static struct lock_file packlock;
@@ -1342,97 +1348,97 @@ int delete_ref(const char *refname, const unsigned char *sha1, int delopt)
*/
#define TMP_RENAMED_LOG "logs/refs/.tmp-renamed-log"
-int rename_ref(const char *oldref, const char *newref, const char *logmsg)
+int rename_ref(const char *oldrefname, const char *newrefname, const char *logmsg)
{
unsigned char sha1[20], orig_sha1[20];
int flag = 0, logmoved = 0;
struct ref_lock *lock;
struct stat loginfo;
- int log = !lstat(git_path("logs/%s", oldref), &loginfo);
+ int log = !lstat(git_path("logs/%s", oldrefname), &loginfo);
const char *symref = NULL;
if (log && S_ISLNK(loginfo.st_mode))
- return error("reflog for %s is a symlink", oldref);
+ return error("reflog for %s is a symlink", oldrefname);
- symref = resolve_ref(oldref, orig_sha1, 1, &flag);
+ symref = resolve_ref(oldrefname, orig_sha1, 1, &flag);
if (flag & REF_ISSYMREF)
return error("refname %s is a symbolic ref, renaming it is not supported",
- oldref);
+ oldrefname);
if (!symref)
- return error("refname %s not found", oldref);
+ return error("refname %s not found", oldrefname);
- if (!is_refname_available(newref, oldref, get_packed_refs(NULL), 0))
+ if (!is_refname_available(newrefname, oldrefname, get_packed_refs(NULL), 0))
return 1;
- if (!is_refname_available(newref, oldref, get_loose_refs(NULL), 0))
+ if (!is_refname_available(newrefname, oldrefname, get_loose_refs(NULL), 0))
return 1;
- if (log && rename(git_path("logs/%s", oldref), git_path(TMP_RENAMED_LOG)))
+ if (log && rename(git_path("logs/%s", oldrefname), git_path(TMP_RENAMED_LOG)))
return error("unable to move logfile logs/%s to "TMP_RENAMED_LOG": %s",
- oldref, strerror(errno));
+ oldrefname, strerror(errno));
- if (delete_ref(oldref, orig_sha1, REF_NODEREF)) {
- error("unable to delete old %s", oldref);
+ if (delete_ref(oldrefname, orig_sha1, REF_NODEREF)) {
+ error("unable to delete old %s", oldrefname);
goto rollback;
}
- if (!read_ref_full(newref, sha1, 1, &flag) &&
- delete_ref(newref, sha1, REF_NODEREF)) {
+ if (!read_ref_full(newrefname, sha1, 1, &flag) &&
+ delete_ref(newrefname, sha1, REF_NODEREF)) {
if (errno==EISDIR) {
- if (remove_empty_directories(git_path("%s", newref))) {
- error("Directory not empty: %s", newref);
+ if (remove_empty_directories(git_path("%s", newrefname))) {
+ error("Directory not empty: %s", newrefname);
goto rollback;
}
} else {
- error("unable to delete existing %s", newref);
+ error("unable to delete existing %s", newrefname);
goto rollback;
}
}
- if (log && safe_create_leading_directories(git_path("logs/%s", newref))) {
- error("unable to create directory for %s", newref);
+ if (log && safe_create_leading_directories(git_path("logs/%s", newrefname))) {
+ error("unable to create directory for %s", newrefname);
goto rollback;
}
retry:
- if (log && rename(git_path(TMP_RENAMED_LOG), git_path("logs/%s", newref))) {
+ if (log && rename(git_path(TMP_RENAMED_LOG), git_path("logs/%s", newrefname))) {
if (errno==EISDIR || errno==ENOTDIR) {
/*
* rename(a, b) when b is an existing
* directory ought to result in ISDIR, but
* Solaris 5.8 gives ENOTDIR. Sheesh.
*/
- if (remove_empty_directories(git_path("logs/%s", newref))) {
- error("Directory not empty: logs/%s", newref);
+ if (remove_empty_directories(git_path("logs/%s", newrefname))) {
+ error("Directory not empty: logs/%s", newrefname);
goto rollback;
}
goto retry;
} else {
error("unable to move logfile "TMP_RENAMED_LOG" to logs/%s: %s",
- newref, strerror(errno));
+ newrefname, strerror(errno));
goto rollback;
}
}
logmoved = log;
- lock = lock_ref_sha1_basic(newref, NULL, 0, NULL);
+ lock = lock_ref_sha1_basic(newrefname, NULL, 0, NULL);
if (!lock) {
- error("unable to lock %s for update", newref);
+ error("unable to lock %s for update", newrefname);
goto rollback;
}
lock->force_write = 1;
hashcpy(lock->old_sha1, orig_sha1);
if (write_ref_sha1(lock, orig_sha1, logmsg)) {
- error("unable to write current sha1 into %s", newref);
+ error("unable to write current sha1 into %s", newrefname);
goto rollback;
}
return 0;
rollback:
- lock = lock_ref_sha1_basic(oldref, NULL, 0, NULL);
+ lock = lock_ref_sha1_basic(oldrefname, NULL, 0, NULL);
if (!lock) {
- error("unable to lock %s for rollback", oldref);
+ error("unable to lock %s for rollback", oldrefname);
goto rollbacklog;
}
@@ -1440,17 +1446,17 @@ int rename_ref(const char *oldref, const char *newref, const char *logmsg)
flag = log_all_ref_updates;
log_all_ref_updates = 0;
if (write_ref_sha1(lock, orig_sha1, NULL))
- error("unable to write current sha1 into %s", oldref);
+ error("unable to write current sha1 into %s", oldrefname);
log_all_ref_updates = flag;
rollbacklog:
- if (logmoved && rename(git_path("logs/%s", newref), git_path("logs/%s", oldref)))
+ if (logmoved && rename(git_path("logs/%s", newrefname), git_path("logs/%s", oldrefname)))
error("unable to restore logfile %s from %s: %s",
- oldref, newref, strerror(errno));
+ oldrefname, newrefname, strerror(errno));
if (!logmoved && log &&
- rename(git_path(TMP_RENAMED_LOG), git_path("logs/%s", oldref)))
+ rename(git_path(TMP_RENAMED_LOG), git_path("logs/%s", oldrefname)))
error("unable to restore logfile %s from "TMP_RENAMED_LOG": %s",
- oldref, strerror(errno));
+ oldrefname, strerror(errno));
return 1;
}
@@ -1507,16 +1513,16 @@ static int copy_msg(char *buf, const char *msg)
return cp - buf;
}
-int log_ref_setup(const char *ref_name, char *logfile, int bufsize)
+int log_ref_setup(const char *refname, char *logfile, int bufsize)
{
int logfd, oflags = O_APPEND | O_WRONLY;
- git_snpath(logfile, bufsize, "logs/%s", ref_name);
+ git_snpath(logfile, bufsize, "logs/%s", refname);
if (log_all_ref_updates &&
- (!prefixcmp(ref_name, "refs/heads/") ||
- !prefixcmp(ref_name, "refs/remotes/") ||
- !prefixcmp(ref_name, "refs/notes/") ||
- !strcmp(ref_name, "HEAD"))) {
+ (!prefixcmp(refname, "refs/heads/") ||
+ !prefixcmp(refname, "refs/remotes/") ||
+ !prefixcmp(refname, "refs/notes/") ||
+ !strcmp(refname, "HEAD"))) {
if (safe_create_leading_directories(logfile) < 0)
return error("unable to create directory for %s",
logfile);
@@ -1546,7 +1552,7 @@ int log_ref_setup(const char *ref_name, char *logfile, int bufsize)
return 0;
}
-static int log_ref_write(const char *ref_name, const unsigned char *old_sha1,
+static int log_ref_write(const char *refname, const unsigned char *old_sha1,
const unsigned char *new_sha1, const char *msg)
{
int logfd, result, written, oflags = O_APPEND | O_WRONLY;
@@ -1559,7 +1565,7 @@ static int log_ref_write(const char *ref_name, const unsigned char *old_sha1,
if (log_all_ref_updates < 0)
log_all_ref_updates = !is_bare_repository();
- result = log_ref_setup(ref_name, log_file, sizeof(log_file));
+ result = log_ref_setup(refname, log_file, sizeof(log_file));
if (result)
return result;
@@ -1730,7 +1736,9 @@ static char *ref_msg(const char *line, const char *endp)
return xmemdupz(line, ep - line);
}
-int read_ref_at(const char *ref, unsigned long at_time, int cnt, unsigned char *sha1, char **msg, unsigned long *cutoff_time, int *cutoff_tz, int *cutoff_cnt)
+int read_ref_at(const char *refname, unsigned long at_time, int cnt,
+ unsigned char *sha1, char **msg,
+ unsigned long *cutoff_time, int *cutoff_tz, int *cutoff_cnt)
{
const char *logfile, *logdata, *logend, *rec, *lastgt, *lastrec;
char *tz_c;
@@ -1741,7 +1749,7 @@ int read_ref_at(const char *ref, unsigned long at_time, int cnt, unsigned char *
void *log_mapped;
size_t mapsz;
- logfile = git_path("logs/%s", ref);
+ logfile = git_path("logs/%s", refname);
logfd = open(logfile, O_RDONLY, 0);
if (logfd < 0)
die_errno("Unable to read log '%s'", logfile);
@@ -1834,14 +1842,14 @@ int read_ref_at(const char *ref, unsigned long at_time, int cnt, unsigned char *
return 1;
}
-int for_each_recent_reflog_ent(const char *ref, each_reflog_ent_fn fn, long ofs, void *cb_data)
+int for_each_recent_reflog_ent(const char *refname, each_reflog_ent_fn fn, long ofs, void *cb_data)
{
const char *logfile;
FILE *logfp;
struct strbuf sb = STRBUF_INIT;
int ret = 0;
- logfile = git_path("logs/%s", ref);
+ logfile = git_path("logs/%s", refname);
logfp = fopen(logfile, "r");
if (!logfp)
return -1;
@@ -1892,9 +1900,9 @@ int for_each_recent_reflog_ent(const char *ref, each_reflog_ent_fn fn, long ofs,
return ret;
}
-int for_each_reflog_ent(const char *ref, each_reflog_ent_fn fn, void *cb_data)
+int for_each_reflog_ent(const char *refname, each_reflog_ent_fn fn, void *cb_data)
{
- return for_each_recent_reflog_ent(ref, fn, 0, cb_data);
+ return for_each_recent_reflog_ent(refname, fn, 0, cb_data);
}
static int do_for_each_reflog(const char *base, each_ref_fn fn, void *cb_data)
@@ -2014,7 +2022,7 @@ static void gen_scanf_fmt(char *scanf_fmt, const char *rule)
return;
}
-char *shorten_unambiguous_ref(const char *ref, int strict)
+char *shorten_unambiguous_ref(const char *refname, int strict)
{
int i;
static char **scanf_fmts;
@@ -2043,10 +2051,10 @@ char *shorten_unambiguous_ref(const char *ref, int strict)
/* bail out if there are no rules */
if (!nr_rules)
- return xstrdup(ref);
+ return xstrdup(refname);
- /* buffer for scanf result, at most ref must fit */
- short_name = xstrdup(ref);
+ /* 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) {
@@ -2054,7 +2062,7 @@ char *shorten_unambiguous_ref(const char *ref, int strict)
int rules_to_fail = i;
int short_name_len;
- if (1 != sscanf(ref, scanf_fmts[i], short_name))
+ if (1 != sscanf(refname, scanf_fmts[i], short_name))
continue;
short_name_len = strlen(short_name);
@@ -2098,5 +2106,5 @@ char *shorten_unambiguous_ref(const char *ref, int strict)
}
free(short_name);
- return xstrdup(ref);
+ return xstrdup(refname);
}
diff --git a/refs.h b/refs.h
index 3fd5536..e36bd03 100644
--- a/refs.h
+++ b/refs.h
@@ -60,14 +60,16 @@ extern void add_extra_ref(const char *refname, const unsigned char *sha1, int fl
extern void clear_extra_refs(void);
extern int ref_exists(const char *);
-extern int peel_ref(const char *, unsigned char *);
+extern int peel_ref(const char *refname, unsigned char *sha1);
/** Locks a "refs/" ref returning the lock on success and NULL on failure. **/
-extern struct ref_lock *lock_ref_sha1(const char *ref, const unsigned char *old_sha1);
+extern struct ref_lock *lock_ref_sha1(const char *refname, const unsigned char *old_sha1);
/** Locks any ref (for 'HEAD' type refs). */
#define REF_NODEREF 0x01
-extern struct ref_lock *lock_any_ref_for_update(const char *ref, const unsigned char *old_sha1, int flags);
+extern struct ref_lock *lock_any_ref_for_update(const char *refname,
+ const unsigned char *old_sha1,
+ int flags);
/** Close the file descriptor owned by a lock and return the status */
extern int close_ref(struct ref_lock *lock);
@@ -93,12 +95,14 @@ extern void invalidate_ref_cache(const char *submodule);
int log_ref_setup(const char *ref_name, char *logfile, int bufsize);
/** Reads log for the value of ref during at_time. **/
-extern int read_ref_at(const char *ref, unsigned long at_time, int cnt, unsigned char *sha1, char **msg, unsigned long *cutoff_time, int *cutoff_tz, int *cutoff_cnt);
+extern int read_ref_at(const char *refname, unsigned long at_time, int cnt,
+ unsigned char *sha1, char **msg,
+ unsigned long *cutoff_time, int *cutoff_tz, int *cutoff_cnt);
/* iterate over reflog entries */
typedef int each_reflog_ent_fn(unsigned char *osha1, unsigned char *nsha1, const char *, unsigned long, int, const char *, void *);
-int for_each_reflog_ent(const char *ref, each_reflog_ent_fn fn, void *cb_data);
-int for_each_recent_reflog_ent(const char *ref, each_reflog_ent_fn fn, long, void *cb_data);
+int for_each_reflog_ent(const char *refname, each_reflog_ent_fn fn, void *cb_data);
+int for_each_recent_reflog_ent(const char *refname, each_reflog_ent_fn fn, long, void *cb_data);
/*
* Calls the specified function for each reflog file until it returns nonzero,
@@ -111,9 +115,9 @@ extern int for_each_reflog(each_ref_fn, void *);
#define REFNAME_DOT_COMPONENT 4
/*
- * Return 0 iff ref has the correct format for a refname according to
- * the rules described in Documentation/git-check-ref-format.txt. If
- * REFNAME_ALLOW_ONELEVEL is set in flags, then accept one-level
+ * Return 0 iff refname has the correct format for a refname according
+ * to the rules described in Documentation/git-check-ref-format.txt.
+ * If REFNAME_ALLOW_ONELEVEL is set in flags, then accept one-level
* reference names. If REFNAME_REFSPEC_PATTERN is set in flags, then
* allow a "*" wildcard character in place of one of the name
* components. No leading or repeated slashes are accepted. If
@@ -121,10 +125,10 @@ extern int for_each_reflog(each_ref_fn, void *);
* components to start with "." (but not a whole component equal to
* "." or "..").
*/
-extern int check_refname_format(const char *ref, int flags);
+extern int check_refname_format(const char *refname, int flags);
extern const char *prettify_refname(const char *refname);
-extern char *shorten_unambiguous_ref(const char *ref, int strict);
+extern char *shorten_unambiguous_ref(const char *refname, int strict);
/** rename ref, return 0 on success **/
extern int rename_ref(const char *oldref, const char *newref, const char *logmsg);
--
1.7.8
^ permalink raw reply related
* [PATCH v2 04/51] clear_ref_array(): rename from free_ref_array()
From: mhagger @ 2011-12-12 5:38 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Jeff King, Drew Northup, Jakub Narebski, Heiko Voigt,
Johan Herland, Julian Phillips, Michael Haggerty
In-Reply-To: <1323668338-1764-1-git-send-email-mhagger@alum.mit.edu>
From: Michael Haggerty <mhagger@alum.mit.edu>
Rename the function since it doesn't actually free the array object
that is passed to it.
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
refs.c | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/refs.c b/refs.c
index 9f7a5ec..7be91d1 100644
--- a/refs.c
+++ b/refs.c
@@ -149,7 +149,7 @@ static struct ref_entry *current_ref;
static struct ref_array extra_refs;
-static void free_ref_array(struct ref_array *array)
+static void clear_ref_array(struct ref_array *array)
{
int i;
for (i = 0; i < array->nr; i++)
@@ -162,14 +162,14 @@ static void free_ref_array(struct ref_array *array)
static void clear_packed_ref_cache(struct ref_cache *refs)
{
if (refs->did_packed)
- free_ref_array(&refs->packed);
+ clear_ref_array(&refs->packed);
refs->did_packed = 0;
}
static void clear_loose_ref_cache(struct ref_cache *refs)
{
if (refs->did_loose)
- free_ref_array(&refs->loose);
+ clear_ref_array(&refs->loose);
refs->did_loose = 0;
}
@@ -256,7 +256,7 @@ void add_extra_ref(const char *refname, const unsigned char *sha1, int flag)
void clear_extra_refs(void)
{
- free_ref_array(&extra_refs);
+ clear_ref_array(&extra_refs);
}
static struct ref_array *get_packed_refs(const char *submodule)
--
1.7.8
^ permalink raw reply related
* [PATCH v2 03/51] refs: rename parameters result -> sha1
From: mhagger @ 2011-12-12 5:38 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Jeff King, Drew Northup, Jakub Narebski, Heiko Voigt,
Johan Herland, Julian Phillips, Michael Haggerty
In-Reply-To: <1323668338-1764-1-git-send-email-mhagger@alum.mit.edu>
From: Michael Haggerty <mhagger@alum.mit.edu>
Try consistently to use the name "sha1" for parameters to which a SHA1
will be stored.
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
refs.c | 20 ++++++++++----------
refs.h | 2 +-
2 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/refs.c b/refs.c
index 8ddd874..9f7a5ec 100644
--- a/refs.c
+++ b/refs.c
@@ -402,7 +402,7 @@ static struct ref_array *get_loose_refs(const char *submodule)
* the packed-refs file for the submodule.
*/
static int resolve_gitlink_packed_ref(char *name, int pathlen,
- const char *refname, unsigned char *result)
+ const char *refname, unsigned char *sha1)
{
int retval = -1;
struct ref_entry *ref;
@@ -415,14 +415,14 @@ static int resolve_gitlink_packed_ref(char *name, int pathlen,
array = get_packed_refs(name);
ref = search_ref_array(array, refname);
if (ref != NULL) {
- memcpy(result, ref->sha1, 20);
+ memcpy(sha1, ref->sha1, 20);
retval = 0;
}
return retval;
}
static int resolve_gitlink_ref_recursive(char *name, int pathlen,
- const char *refname, unsigned char *result,
+ const char *refname, unsigned char *sha1,
int recursion)
{
int fd, len = strlen(refname);
@@ -433,7 +433,7 @@ static int resolve_gitlink_ref_recursive(char *name, int pathlen,
memcpy(name + pathlen, refname, len+1);
fd = open(name, O_RDONLY);
if (fd < 0)
- return resolve_gitlink_packed_ref(name, pathlen, refname, result);
+ return resolve_gitlink_packed_ref(name, pathlen, refname, sha1);
len = read(fd, buffer, sizeof(buffer)-1);
close(fd);
@@ -444,7 +444,7 @@ static int resolve_gitlink_ref_recursive(char *name, int pathlen,
buffer[len] = 0;
/* Was it a detached head or an old-fashioned symlink? */
- if (!get_sha1_hex(buffer, result))
+ if (!get_sha1_hex(buffer, sha1))
return 0;
/* Symref? */
@@ -454,10 +454,10 @@ static int resolve_gitlink_ref_recursive(char *name, int pathlen,
while (isspace(*p))
p++;
- return resolve_gitlink_ref_recursive(name, pathlen, p, result, recursion+1);
+ return resolve_gitlink_ref_recursive(name, pathlen, p, sha1, recursion+1);
}
-int resolve_gitlink_ref(const char *path, const char *refname, unsigned char *result)
+int resolve_gitlink_ref(const char *path, const char *refname, unsigned char *sha1)
{
int len = strlen(path), retval;
char *gitdir;
@@ -481,7 +481,7 @@ int resolve_gitlink_ref(const char *path, const char *refname, unsigned char *re
}
gitdir[len] = '/';
gitdir[++len] = '\0';
- retval = resolve_gitlink_ref_recursive(gitdir, len, refname, result, 0);
+ retval = resolve_gitlink_ref_recursive(gitdir, len, refname, sha1, 0);
free(gitdir);
return retval;
}
@@ -647,13 +647,13 @@ static int do_one_ref(const char *base, each_ref_fn fn, int trim,
return fn(entry->name + trim, entry->sha1, entry->flag, cb_data);
}
-static int filter_refs(const char *refname, const unsigned char *sha, int flags,
+static int filter_refs(const char *refname, const unsigned char *sha1, int flags,
void *data)
{
struct ref_filter *filter = (struct ref_filter *)data;
if (fnmatch(filter->pattern, refname, 0))
return 0;
- return filter->fn(refname, sha, flags, filter->cb_data);
+ return filter->fn(refname, sha1, flags, filter->cb_data);
}
int peel_ref(const char *refname, unsigned char *sha1)
diff --git a/refs.h b/refs.h
index e36bd03..4c5d570 100644
--- a/refs.h
+++ b/refs.h
@@ -134,7 +134,7 @@ extern char *shorten_unambiguous_ref(const char *refname, int strict);
extern int rename_ref(const char *oldref, const char *newref, const char *logmsg);
/** resolve ref in nested "gitlink" repository */
-extern int resolve_gitlink_ref(const char *name, const char *refname, unsigned char *result);
+extern int resolve_gitlink_ref(const char *name, const char *refname, unsigned char *sha1);
/** lock a ref and then write its file */
enum action_on_err { MSG_ON_ERR, DIE_ON_ERR, QUIET_ON_ERR };
--
1.7.8
^ permalink raw reply related
* [PATCH v2 01/51] struct ref_entry: document name member
From: mhagger @ 2011-12-12 5:38 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Jeff King, Drew Northup, Jakub Narebski, Heiko Voigt,
Johan Herland, Julian Phillips, Michael Haggerty
In-Reply-To: <1323668338-1764-1-git-send-email-mhagger@alum.mit.edu>
From: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
refs.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/refs.c b/refs.c
index f5cb297..669782f 100644
--- a/refs.c
+++ b/refs.c
@@ -11,6 +11,7 @@ struct ref_entry {
unsigned char flag; /* ISSYMREF? ISPACKED? */
unsigned char sha1[20];
unsigned char peeled[20];
+ /* The full name of the reference (e.g., "refs/heads/master"): */
char name[FLEX_ARRAY];
};
--
1.7.8
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox