}
/*
- * A loose ref file doesn't exist; check for a packed ref. The
- * options are forwarded from resolve_safe_unsafe().
+ * A loose ref file doesn't exist; check for a packed ref.
*/
static int resolve_missing_loose_ref(const char *refname,
- int resolve_flags,
unsigned char *sha1,
int *flags)
{
entry = get_packed_ref(refname);
if (entry) {
hashcpy(sha1, entry->u.value.oid.hash);
- if (flags)
- *flags |= REF_ISPACKED;
- return 0;
- }
- /* The reference is not a packed reference, either. */
- if (resolve_flags & RESOLVE_REF_READING) {
- errno = ENOENT;
- return -1;
- } else {
- hashclr(sha1);
+ *flags |= REF_ISPACKED;
return 0;
}
+ /* refname is not a packed reference. */
+ return -1;
}
/* This function needs to return a meaningful errno on failure */
struct strbuf *sb_path,
struct strbuf *sb_contents)
{
- int depth = MAXDEPTH;
int bad_name = 0;
+ int symref_count;
- if (flags)
- *flags = 0;
+ *flags = 0;
if (check_refname_format(refname, REFNAME_ALLOW_ONELEVEL)) {
- if (flags)
- *flags |= REF_BAD_NAME;
+ *flags |= REF_BAD_NAME;
if (!(resolve_flags & RESOLVE_REF_ALLOW_BAD_NAME) ||
!refname_is_safe(refname)) {
*/
bad_name = 1;
}
- for (;;) {
+
+ for (symref_count = 0; symref_count < MAXDEPTH; symref_count++) {
const char *path;
struct stat st;
char *buf;
int fd;
- if (--depth < 0) {
- errno = ELOOP;
- return NULL;
- }
-
strbuf_reset(sb_path);
strbuf_git_path(sb_path, "%s", refname);
path = sb_path->buf;
if (lstat(path, &st) < 0) {
if (errno != ENOENT)
return NULL;
- if (resolve_missing_loose_ref(refname, resolve_flags,
- sha1, flags))
- return NULL;
+ if (resolve_missing_loose_ref(refname, sha1, flags)) {
+ if (resolve_flags & RESOLVE_REF_READING) {
+ errno = ENOENT;
+ return NULL;
+ }
+ hashclr(sha1);
+ }
if (bad_name) {
hashclr(sha1);
- if (flags)
- *flags |= REF_ISBROKEN;
+ *flags |= REF_ISBROKEN;
}
return refname;
}
!check_refname_format(sb_contents->buf, 0)) {
strbuf_swap(sb_refname, sb_contents);
refname = sb_refname->buf;
- if (flags)
- *flags |= REF_ISSYMREF;
+ *flags |= REF_ISSYMREF;
if (resolve_flags & RESOLVE_REF_NO_RECURSE) {
hashclr(sha1);
return refname;
*/
if (get_sha1_hex(sb_contents->buf, sha1) ||
(sb_contents->buf[40] != '\0' && !isspace(sb_contents->buf[40]))) {
- if (flags)
- *flags |= REF_ISBROKEN;
+ *flags |= REF_ISBROKEN;
errno = EINVAL;
return NULL;
}
if (bad_name) {
hashclr(sha1);
- if (flags)
- *flags |= REF_ISBROKEN;
+ *flags |= REF_ISBROKEN;
}
return refname;
}
- if (flags)
- *flags |= REF_ISSYMREF;
+ *flags |= REF_ISSYMREF;
buf = sb_contents->buf + 4;
while (isspace(*buf))
buf++;
return refname;
}
if (check_refname_format(buf, REFNAME_ALLOW_ONELEVEL)) {
- if (flags)
- *flags |= REF_ISBROKEN;
+ *flags |= REF_ISBROKEN;
if (!(resolve_flags & RESOLVE_REF_ALLOW_BAD_NAME) ||
!refname_is_safe(buf)) {
bad_name = 1;
}
}
+
+ errno = ELOOP;
+ return NULL;
}
const char *resolve_ref_unsafe(const char *refname, int resolve_flags,
static struct strbuf sb_refname = STRBUF_INIT;
struct strbuf sb_contents = STRBUF_INIT;
struct strbuf sb_path = STRBUF_INIT;
+ int unused_flags;
const char *ret;
+ if (!flags)
+ flags = &unused_flags;
+
ret = resolve_ref_1(refname, resolve_flags, sha1, flags,
&sb_refname, &sb_path, &sb_contents);
strbuf_release(&sb_path);