Skip to content

Commit 9a489f3

Browse files
mhaggergitster
authored andcommitted
refs: extract a function peel_entry()
Peel the entry, and as a side effect store the peeled value in the entry. Use this function from two places in peel_ref(); a third caller will be added soon. Please note that this change can lead to ref_entries for unpacked refs being peeled. This has no practical benefit but is harmless. Signed-off-by: Michael Haggerty <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 2312a79 commit 9a489f3

File tree

1 file changed

+49
-14
lines changed

1 file changed

+49
-14
lines changed

refs.c

Lines changed: 49 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1286,7 +1286,17 @@ enum peel_status {
12861286
PEEL_INVALID = -1,
12871287

12881288
/* object cannot be peeled because it is not a tag: */
1289-
PEEL_NON_TAG = -2
1289+
PEEL_NON_TAG = -2,
1290+
1291+
/* ref_entry contains no peeled value because it is a symref: */
1292+
PEEL_IS_SYMREF = -3,
1293+
1294+
/*
1295+
* ref_entry cannot be peeled because it is broken (i.e., the
1296+
* symbolic reference cannot even be resolved to an object
1297+
* name):
1298+
*/
1299+
PEEL_BROKEN = -4
12901300
};
12911301

12921302
/*
@@ -1318,31 +1328,56 @@ static enum peel_status peel_object(const unsigned char *name, unsigned char *sh
13181328
return PEEL_PEELED;
13191329
}
13201330

1331+
/*
1332+
* Peel the entry (if possible) and return its new peel_status.
1333+
*/
1334+
static enum peel_status peel_entry(struct ref_entry *entry)
1335+
{
1336+
enum peel_status status;
1337+
1338+
if (entry->flag & REF_KNOWS_PEELED)
1339+
return is_null_sha1(entry->u.value.peeled) ?
1340+
PEEL_NON_TAG : PEEL_PEELED;
1341+
if (entry->flag & REF_ISBROKEN)
1342+
return PEEL_BROKEN;
1343+
if (entry->flag & REF_ISSYMREF)
1344+
return PEEL_IS_SYMREF;
1345+
1346+
status = peel_object(entry->u.value.sha1, entry->u.value.peeled);
1347+
if (status == PEEL_PEELED || status == PEEL_NON_TAG)
1348+
entry->flag |= REF_KNOWS_PEELED;
1349+
return status;
1350+
}
1351+
13211352
int peel_ref(const char *refname, unsigned char *sha1)
13221353
{
13231354
int flag;
13241355
unsigned char base[20];
13251356

13261357
if (current_ref && (current_ref->name == refname
1327-
|| !strcmp(current_ref->name, refname))) {
1328-
if (current_ref->flag & REF_KNOWS_PEELED) {
1329-
if (is_null_sha1(current_ref->u.value.peeled))
1330-
return -1;
1331-
hashcpy(sha1, current_ref->u.value.peeled);
1332-
return 0;
1333-
}
1334-
return peel_object(current_ref->u.value.sha1, sha1);
1358+
|| !strcmp(current_ref->name, refname))) {
1359+
if (peel_entry(current_ref))
1360+
return -1;
1361+
hashcpy(sha1, current_ref->u.value.peeled);
1362+
return 0;
13351363
}
13361364

13371365
if (read_ref_full(refname, base, 1, &flag))
13381366
return -1;
13391367

1340-
if ((flag & REF_ISPACKED)) {
1368+
/*
1369+
* If the reference is packed, read its ref_entry from the
1370+
* cache in the hope that we already know its peeled value.
1371+
* We only try this optimization on packed references because
1372+
* (a) forcing the filling of the loose reference cache could
1373+
* be expensive and (b) loose references anyway usually do not
1374+
* have REF_KNOWS_PEELED.
1375+
*/
1376+
if (flag & REF_ISPACKED) {
13411377
struct ref_entry *r = get_packed_ref(refname);
1342-
1343-
if (r && (r->flag & REF_KNOWS_PEELED)) {
1344-
if (is_null_sha1(r->u.value.peeled))
1345-
return -1;
1378+
if (r) {
1379+
if (peel_entry(r))
1380+
return -1;
13461381
hashcpy(sha1, r->u.value.peeled);
13471382
return 0;
13481383
}

0 commit comments

Comments
 (0)