last_line, eof - last_line);
}
+#define SMALL_FILE_SIZE (32*1024)
+
/*
* Depending on `mmap_strategy`, either mmap or read the contents of
* the `packed-refs` file into the snapshot. Return 1 if the file
- * existed and was read, or 0 if the file was absent. Die on errors.
+ * existed and was read, or 0 if the file was absent or empty. Die on
+ * errors.
*/
static int load_contents(struct snapshot *snapshot)
{
die_errno("couldn't stat %s", snapshot->refs->path);
size = xsize_t(st.st_size);
- switch (mmap_strategy) {
- case MMAP_NONE:
+ if (!size) {
+ return 0;
+ } else if (mmap_strategy == MMAP_NONE || size <= SMALL_FILE_SIZE) {
snapshot->buf = xmalloc(size);
bytes_read = read_in_full(fd, snapshot->buf, size);
if (bytes_read < 0 || bytes_read != size)
die_errno("couldn't read %s", snapshot->refs->path);
snapshot->mmapped = 0;
- break;
- case MMAP_TEMPORARY:
- case MMAP_OK:
+ } else {
snapshot->buf = xmmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
snapshot->mmapped = 1;
- break;
}
close(fd);
* `refname` starts. If `mustexist` is true and the reference doesn't
* exist, then return NULL. If `mustexist` is false and the reference
* doesn't exist, then return the point where that reference would be
- * inserted. In the latter mode, `refname` doesn't have to be a proper
- * reference name; for example, one could search for "refs/replace/"
- * to find the start of any replace references.
+ * inserted, or `snapshot->eof` (which might be NULL) if it would be
+ * inserted at the end of the file. In the latter mode, `refname`
+ * doesn't have to be a proper reference name; for example, one could
+ * search for "refs/replace/" to find the start of any replace
+ * references.
*
* The record is sought using a binary search, so `snapshot->buf` must
* be sorted.
*/
const char *hi = snapshot->eof;
- while (lo < hi) {
+ while (lo != hi) {
const char *mid, *rec;
int cmp;
}
static int packed_read_raw_ref(struct ref_store *ref_store,
- const char *refname, unsigned char *sha1,
+ const char *refname, struct object_id *oid,
struct strbuf *referent, unsigned int *type)
{
struct packed_ref_store *refs =
return -1;
}
- if (get_sha1_hex(rec, sha1))
+ if (get_oid_hex(rec, oid))
die_invalid_line(refs->path, rec, snapshot->eof - rec);
*type = REF_ISPACKED;
/*
* This value is set in `base.flags` if the peeled value of the
* current reference is known. In that case, `peeled` contains the
- * correct peeled value for the reference, which might be `null_sha1`
+ * correct peeled value for the reference, which might be `null_oid`
* if the reference is not a tag or if it is broken.
*/
#define REF_KNOWS_PEELED 0x40
} else if ((iter->base.flags & (REF_ISBROKEN | REF_ISSYMREF))) {
return -1;
} else {
- return !!peel_object(iter->oid.hash, peeled->hash);
+ return !!peel_object(&iter->oid, peeled);
}
}
*/
snapshot = get_snapshot(refs);
- if (!snapshot->buf)
+ if (prefix && *prefix)
+ start = find_reference_location(snapshot, prefix, 0);
+ else
+ start = snapshot->start;
+
+ if (start == snapshot->eof)
return empty_ref_iterator_begin();
iter = xcalloc(1, sizeof(*iter));
iter->snapshot = snapshot;
acquire_snapshot(snapshot);
- if (prefix && *prefix)
- start = find_reference_location(snapshot, prefix, 0);
- else
- start = snapshot->start;
-
iter->pos = start;
iter->eof = snapshot->eof;
strbuf_init(&iter->refname_buf, 0);
* by the failing call to `fprintf()`.
*/
static int write_packed_entry(FILE *fh, const char *refname,
- const unsigned char *sha1,
- const unsigned char *peeled)
+ const struct object_id *oid,
+ const struct object_id *peeled)
{
- if (fprintf(fh, "%s %s\n", sha1_to_hex(sha1), refname) < 0 ||
- (peeled && fprintf(fh, "^%s\n", sha1_to_hex(peeled)) < 0))
+ if (fprintf(fh, "%s %s\n", oid_to_hex(oid), refname) < 0 ||
+ (peeled && fprintf(fh, "^%s\n", oid_to_hex(peeled)) < 0))
return -1;
return 0;
int peel_error = ref_iterator_peel(iter, &peeled);
if (write_packed_entry(out, iter->refname,
- iter->oid->hash,
- peel_error ? NULL : peeled.hash))
+ iter->oid,
+ peel_error ? NULL : &peeled))
goto write_error;
if ((ok = ref_iterator_advance(iter)) != ITER_OK)
i++;
} else {
struct object_id peeled;
- int peel_error = peel_object(update->new_oid.hash,
- peeled.hash);
+ int peel_error = peel_object(&update->new_oid,
+ &peeled);
if (write_packed_entry(out, update->refname,
- update->new_oid.hash,
- peel_error ? NULL : peeled.hash))
+ &update->new_oid,
+ peel_error ? NULL : &peeled))
goto write_error;
i++;
continue;
if (!refs_read_raw_ref(ref_store, update->refname,
- oid.hash, &referent, &type) ||
+ &oid, &referent, &type) ||
errno != ENOENT) {
/*
* We have to actually delete that reference
}
static int packed_reflog_expire(struct ref_store *ref_store,
- const char *refname, const unsigned char *sha1,
+ const char *refname, const struct object_id *oid,
unsigned int flags,
reflog_expiry_prepare_fn prepare_fn,
reflog_expiry_should_prune_fn should_prune_fn,