static int unreachable(struct expire_reflog_policy_cb *cb, struct commit *commit, struct object_id *oid) { /* * We may or may not have the commit yet - if not, look it * up using the supplied sha1. */ if (!commit) { if (is_null_oid(oid)) return 0; commit = lookup_commit_reference_gently(the_repository, oid, 1); /* Not a commit -- keep it */ if (!commit) return 0; } /* Reachable from the current ref? Don't prune. */ if (commit->object.flags & REACHABLE) return 0; if (cb->mark_list && cb->mark_limit) { cb->mark_limit = 0; /* dig down to the root */ mark_reachable(cb); } return !(commit->object.flags & REACHABLE); }
static void mark_reachable (latnode_t *from) { latlink_t *link; from->reachable = TRUE; for (link = from->links; link; link = link->next) { if (! link->to->reachable) mark_reachable (link->to); } }
void mark_reachable(struct object *obj, unsigned int mask) { struct object_list *p = obj->refs; /* If we've been here already, don't bother */ if (obj->flags & mask) return; obj->flags |= mask; while (p) { mark_reachable(p->item, mask); p = p->next; } }
static void reflog_expiry_prepare(const char *refname, const struct object_id *oid, void *cb_data) { struct expire_reflog_policy_cb *cb = cb_data; if (!cb->cmd.expire_unreachable || is_head(refname)) { cb->tip_commit = NULL; cb->unreachable_expire_kind = UE_HEAD; } else { cb->tip_commit = lookup_commit_reference_gently(the_repository, oid, 1); if (!cb->tip_commit) cb->unreachable_expire_kind = UE_ALWAYS; else cb->unreachable_expire_kind = UE_NORMAL; } if (cb->cmd.expire_unreachable <= cb->cmd.expire_total) cb->unreachable_expire_kind = UE_ALWAYS; cb->mark_list = NULL; cb->tips = NULL; if (cb->unreachable_expire_kind != UE_ALWAYS) { if (cb->unreachable_expire_kind == UE_HEAD) { struct commit_list *elem; for_each_ref(push_tip_to_list, &cb->tips); for (elem = cb->tips; elem; elem = elem->next) commit_list_insert(elem->item, &cb->mark_list); } else { commit_list_insert(cb->tip_commit, &cb->mark_list); } cb->mark_limit = cb->cmd.expire_total; mark_reachable(cb); } }