Skip to content

Commit 50c2d85

Browse files
mhaggergitster
authored andcommitted
files_pack_refs(): use reference iteration
Use reference iteration rather than `do_for_each_entry_in_dir()` in the definition of `files_pack_refs()`. This makes the code shorter and easier to follow, because the logic can be inline rather than spread between the main function and a callback function, and it removes the need to use `pack_refs_cb_data` to preserve intermediate state. This removes the last callers of `entry_resolves_to_object()` and `get_loose_ref_dir()`, so delete those functions. Signed-off-by: Michael Haggerty <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 1710fba commit 50c2d85

File tree

1 file changed

+60
-83
lines changed

1 file changed

+60
-83
lines changed

refs/files-backend.c

Lines changed: 60 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -32,17 +32,6 @@ static int ref_resolves_to_object(const char *refname,
3232
return 1;
3333
}
3434

35-
/*
36-
* Return true if the reference described by entry can be resolved to
37-
* an object in the database; otherwise, emit a warning and return
38-
* false.
39-
*/
40-
static int entry_resolves_to_object(struct ref_entry *entry)
41-
{
42-
return ref_resolves_to_object(entry->name,
43-
&entry->u.value.oid, entry->flag);
44-
}
45-
4635
struct packed_ref_cache {
4736
struct ref_cache *cache;
4837

@@ -547,11 +536,6 @@ static struct ref_cache *get_loose_ref_cache(struct files_ref_store *refs)
547536
return refs->loose;
548537
}
549538

550-
static struct ref_dir *get_loose_ref_dir(struct files_ref_store *refs)
551-
{
552-
return get_ref_dir(get_loose_ref_cache(refs)->root);
553-
}
554-
555539
/*
556540
* Return the ref_entry for the given refname from the packed
557541
* references. If it does not exist, return NULL.
@@ -1408,65 +1392,6 @@ struct ref_to_prune {
14081392
char name[FLEX_ARRAY];
14091393
};
14101394

1411-
struct pack_refs_cb_data {
1412-
unsigned int flags;
1413-
struct ref_dir *packed_refs;
1414-
struct ref_to_prune *ref_to_prune;
1415-
};
1416-
1417-
/*
1418-
* An each_ref_entry_fn that is run over loose references only. If
1419-
* the loose reference can be packed, add an entry in the packed ref
1420-
* cache. If the reference should be pruned, also add it to
1421-
* ref_to_prune in the pack_refs_cb_data.
1422-
*/
1423-
static int pack_if_possible_fn(struct ref_entry *entry, void *cb_data)
1424-
{
1425-
struct pack_refs_cb_data *cb = cb_data;
1426-
enum peel_status peel_status;
1427-
struct ref_entry *packed_entry;
1428-
int is_tag_ref = starts_with(entry->name, "refs/tags/");
1429-
1430-
/* Do not pack per-worktree refs: */
1431-
if (ref_type(entry->name) != REF_TYPE_NORMAL)
1432-
return 0;
1433-
1434-
/* ALWAYS pack tags */
1435-
if (!(cb->flags & PACK_REFS_ALL) && !is_tag_ref)
1436-
return 0;
1437-
1438-
/* Do not pack symbolic or broken refs: */
1439-
if ((entry->flag & REF_ISSYMREF) || !entry_resolves_to_object(entry))
1440-
return 0;
1441-
1442-
/* Add a packed ref cache entry equivalent to the loose entry. */
1443-
peel_status = peel_entry(entry, 1);
1444-
if (peel_status != PEEL_PEELED && peel_status != PEEL_NON_TAG)
1445-
die("internal error peeling reference %s (%s)",
1446-
entry->name, oid_to_hex(&entry->u.value.oid));
1447-
packed_entry = find_ref_entry(cb->packed_refs, entry->name);
1448-
if (packed_entry) {
1449-
/* Overwrite existing packed entry with info from loose entry */
1450-
packed_entry->flag = REF_ISPACKED | REF_KNOWS_PEELED;
1451-
oidcpy(&packed_entry->u.value.oid, &entry->u.value.oid);
1452-
} else {
1453-
packed_entry = create_ref_entry(entry->name, entry->u.value.oid.hash,
1454-
REF_ISPACKED | REF_KNOWS_PEELED, 0);
1455-
add_ref_entry(cb->packed_refs, packed_entry);
1456-
}
1457-
oidcpy(&packed_entry->u.value.peeled, &entry->u.value.peeled);
1458-
1459-
/* Schedule the loose reference for pruning if requested. */
1460-
if ((cb->flags & PACK_REFS_PRUNE)) {
1461-
struct ref_to_prune *n;
1462-
FLEX_ALLOC_STR(n, name, entry->name);
1463-
hashcpy(n->sha1, entry->u.value.oid.hash);
1464-
n->next = cb->ref_to_prune;
1465-
cb->ref_to_prune = n;
1466-
}
1467-
return 0;
1468-
}
1469-
14701395
enum {
14711396
REMOVE_EMPTY_PARENTS_REF = 0x01,
14721397
REMOVE_EMPTY_PARENTS_REFLOG = 0x02
@@ -1556,21 +1481,73 @@ static int files_pack_refs(struct ref_store *ref_store, unsigned int flags)
15561481
struct files_ref_store *refs =
15571482
files_downcast(ref_store, REF_STORE_WRITE | REF_STORE_ODB,
15581483
"pack_refs");
1559-
struct pack_refs_cb_data cbdata;
1560-
1561-
memset(&cbdata, 0, sizeof(cbdata));
1562-
cbdata.flags = flags;
1484+
struct ref_iterator *iter;
1485+
struct ref_dir *packed_refs;
1486+
int ok;
1487+
struct ref_to_prune *refs_to_prune = NULL;
15631488

15641489
lock_packed_refs(refs, LOCK_DIE_ON_ERROR);
1565-
cbdata.packed_refs = get_packed_refs(refs);
1490+
packed_refs = get_packed_refs(refs);
1491+
1492+
iter = cache_ref_iterator_begin(get_loose_ref_cache(refs), NULL, 0);
1493+
while ((ok = ref_iterator_advance(iter)) == ITER_OK) {
1494+
/*
1495+
* If the loose reference can be packed, add an entry
1496+
* in the packed ref cache. If the reference should be
1497+
* pruned, also add it to refs_to_prune.
1498+
*/
1499+
struct ref_entry *packed_entry;
1500+
int is_tag_ref = starts_with(iter->refname, "refs/tags/");
1501+
1502+
/* Do not pack per-worktree refs: */
1503+
if (ref_type(iter->refname) != REF_TYPE_NORMAL)
1504+
continue;
1505+
1506+
/* ALWAYS pack tags */
1507+
if (!(flags & PACK_REFS_ALL) && !is_tag_ref)
1508+
continue;
1509+
1510+
/* Do not pack symbolic or broken refs: */
1511+
if (iter->flags & REF_ISSYMREF)
1512+
continue;
15661513

1567-
do_for_each_entry_in_dir(get_loose_ref_dir(refs),
1568-
pack_if_possible_fn, &cbdata);
1514+
if (!ref_resolves_to_object(iter->refname, iter->oid, iter->flags))
1515+
continue;
1516+
1517+
/*
1518+
* Create an entry in the packed-refs cache equivalent
1519+
* to the one from the loose ref cache, except that
1520+
* we don't copy the peeled status, because we want it
1521+
* to be re-peeled.
1522+
*/
1523+
packed_entry = find_ref_entry(packed_refs, iter->refname);
1524+
if (packed_entry) {
1525+
/* Overwrite existing packed entry with info from loose entry */
1526+
packed_entry->flag = REF_ISPACKED;
1527+
oidcpy(&packed_entry->u.value.oid, iter->oid);
1528+
} else {
1529+
packed_entry = create_ref_entry(iter->refname, iter->oid->hash,
1530+
REF_ISPACKED, 0);
1531+
add_ref_entry(packed_refs, packed_entry);
1532+
}
1533+
oidclr(&packed_entry->u.value.peeled);
1534+
1535+
/* Schedule the loose reference for pruning if requested. */
1536+
if ((flags & PACK_REFS_PRUNE)) {
1537+
struct ref_to_prune *n;
1538+
FLEX_ALLOC_STR(n, name, iter->refname);
1539+
hashcpy(n->sha1, iter->oid->hash);
1540+
n->next = refs_to_prune;
1541+
refs_to_prune = n;
1542+
}
1543+
}
1544+
if (ok != ITER_DONE)
1545+
die("error while iterating over references");
15691546

15701547
if (commit_packed_refs(refs))
15711548
die_errno("unable to overwrite old ref-pack file");
15721549

1573-
prune_refs(refs, cbdata.ref_to_prune);
1550+
prune_refs(refs, refs_to_prune);
15741551
return 0;
15751552
}
15761553

0 commit comments

Comments
 (0)