*/
static const struct ref_storage_be *refs_backends[] = {
[REF_STORAGE_FORMAT_FILES] = &refs_be_files,
+ [REF_STORAGE_FORMAT_REFTABLE] = &refs_be_reftable,
};
static const struct ref_storage_be *find_ref_storage_backend(unsigned int ref_storage_format)
return 1;
}
+int is_pseudoref(struct ref_store *refs, const char *refname)
+{
+ static const char *const irregular_pseudorefs[] = {
+ "AUTO_MERGE",
+ "BISECT_EXPECTED_REV",
+ "NOTES_MERGE_PARTIAL",
+ "NOTES_MERGE_REF",
+ "MERGE_AUTOSTASH",
+ };
+ struct object_id oid;
+ size_t i;
+
+ if (!is_pseudoref_syntax(refname))
+ return 0;
+
+ if (ends_with(refname, "_HEAD")) {
+ refs_resolve_ref_unsafe(refs, refname,
+ RESOLVE_REF_READING | RESOLVE_REF_NO_RECURSE,
+ &oid, NULL);
+ return !is_null_oid(&oid);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(irregular_pseudorefs); i++)
+ if (!strcmp(refname, irregular_pseudorefs[i])) {
+ refs_resolve_ref_unsafe(refs, refname,
+ RESOLVE_REF_READING | RESOLVE_REF_NO_RECURSE,
+ &oid, NULL);
+ return !is_null_oid(&oid);
+ }
+
+ return 0;
+}
+
+int is_headref(struct ref_store *refs, const char *refname)
+{
+ if (!strcmp(refname, "HEAD"))
+ return refs_ref_exists(refs, refname);
+
+ return 0;
+}
+
static int is_current_worktree_ref(const char *ref) {
return is_pseudoref_syntax(ref) || is_per_worktree_ref(ref);
}
refs_for_each_reflog_ent_reverse(refs, refname, read_ref_at_ent, &cb);
if (!cb.reccnt) {
+ if (cnt == 0) {
+ /*
+ * The caller asked for ref@{0}, and we had no entries.
+ * It's a bit subtle, but in practice all callers have
+ * prepped the "oid" field with the current value of
+ * the ref, which is the most reasonable fallback.
+ *
+ * We'll put dummy values into the out-parameters (so
+ * they're not just uninitialized garbage), and the
+ * caller can take our return value as a hint that
+ * we did not find any such reflog.
+ */
+ set_read_ref_cutoffs(&cb, 0, 0, "empty reflog");
+ return 1;
+ }
if (flags & GET_OID_QUIETLY)
exit(128);
else
if (trim)
iter = prefix_ref_iterator_begin(iter, "", trim);
- /* Sanity check for subclasses: */
- if (!iter->ordered)
- BUG("reference iterator is not ordered");
-
return iter;
}
return refs_for_each_rawref(get_main_ref_store(the_repository), fn, cb_data);
}
+int refs_for_each_include_root_refs(struct ref_store *refs, each_ref_fn fn,
+ void *cb_data)
+{
+ return do_for_each_ref(refs, "", NULL, fn, 0,
+ DO_FOR_EACH_INCLUDE_ROOT_REFS, cb_data);
+}
+
static int qsort_strcmp(const void *va, const void *vb)
{
const char *a = *(const char **)va;
return ret;
}
-int refs_for_each_reflog(struct ref_store *refs, each_ref_fn fn, void *cb_data)
+struct do_for_each_reflog_help {
+ each_reflog_fn *fn;
+ void *cb_data;
+};
+
+static int do_for_each_reflog_helper(struct repository *r UNUSED,
+ const char *refname,
+ const struct object_id *oid UNUSED,
+ int flags,
+ void *cb_data)
+{
+ struct do_for_each_reflog_help *hp = cb_data;
+ return hp->fn(refname, hp->cb_data);
+}
+
+int refs_for_each_reflog(struct ref_store *refs, each_reflog_fn fn, void *cb_data)
{
struct ref_iterator *iter;
- struct do_for_each_ref_help hp = { fn, cb_data };
+ struct do_for_each_reflog_help hp = { fn, cb_data };
iter = refs->be->reflog_iterator_begin(refs);
return do_for_each_repo_ref_iterator(the_repository, iter,
- do_for_each_ref_helper, &hp);
+ do_for_each_reflog_helper, &hp);
}
-int for_each_reflog(each_ref_fn fn, void *cb_data)
+int for_each_reflog(each_reflog_fn fn, void *cb_data)
{
return refs_for_each_reflog(get_main_ref_store(the_repository), fn, cb_data);
}