aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--refs.c5
-rw-r--r--refs.h8
2 files changed, 12 insertions, 1 deletions
diff --git a/refs.c b/refs.c
index 7405d1c96..787db21df 100644
--- a/refs.c
+++ b/refs.c
@@ -119,7 +119,8 @@ struct ref_value {
/*
* If REF_KNOWS_PEELED, then this field holds the peeled value
* of this reference, or null if the reference is known not to
- * be peelable.
+ * be peelable. See the documentation for peel_ref() for an
+ * exact definition of "peelable".
*/
unsigned char peeled[20];
};
@@ -1340,6 +1341,8 @@ int peel_ref(const char *refname, unsigned char *sha1)
struct ref_entry *r = get_packed_ref(refname);
if (r && (r->flag & REF_KNOWS_PEELED)) {
+ if (is_null_sha1(r->u.value.peeled))
+ return -1;
hashcpy(sha1, r->u.value.peeled);
return 0;
}
diff --git a/refs.h b/refs.h
index f111024a1..3fc97a2e4 100644
--- a/refs.h
+++ b/refs.h
@@ -74,6 +74,14 @@ extern void add_packed_ref(const char *refname, const unsigned char *sha1);
extern int ref_exists(const char *);
+/*
+ * If refname is a non-symbolic reference that refers to a tag object,
+ * and the tag can be (recursively) dereferenced to a non-tag object,
+ * store the SHA1 of the referred-to object to sha1 and return 0. If
+ * any of these conditions are not met, return a non-zero value.
+ * Symbolic references are considered unpeelable, even if they
+ * ultimately resolve to a peelable tag.
+ */
extern int peel_ref(const char *refname, unsigned char *sha1);
/** Locks a "refs/" ref returning the lock on success and NULL on failure. **/